diff --git a/1-js/06-advanced-functions/01-recursion/01-sum-to/solution.md b/1-js/06-advanced-functions/01-recursion/01-sum-to/solution.md
index 11667f940..22248b9b4 100644
--- a/1-js/06-advanced-functions/01-recursion/01-sum-to/solution.md
+++ b/1-js/06-advanced-functions/01-recursion/01-sum-to/solution.md
@@ -1,4 +1,4 @@
-The solution using a loop:
+Løsningen ved brug af et `for`-loop:
```js run
function sumTo(n) {
@@ -12,7 +12,7 @@ function sumTo(n) {
alert( sumTo(100) );
```
-The solution using recursion:
+Løsningen der bruger rekursion:
```js run
function sumTo(n) {
@@ -23,7 +23,7 @@ function sumTo(n) {
alert( sumTo(100) );
```
-The solution using the formula: `sumTo(n) = n*(n+1)/2`:
+Løsningnen der bruger formlen: `sumTo(n) = n*(n+1)/2`:
```js run
function sumTo(n) {
@@ -33,8 +33,8 @@ function sumTo(n) {
alert( sumTo(100) );
```
-P.S. Naturally, the formula is the fastest solution. It uses only 3 operations for any number `n`. The math helps!
+P.S. Naturligvis er formlen den hurtigste løsning. Den bruger kun 3 operationer for ethvert tal `n`. Matematikken hjælper!
-The loop variant is the second in terms of speed. In both the recursive and the loop variant we sum the same numbers. But the recursion involves nested calls and execution stack management. That also takes resources, so it's slower.
+Loop-varianten er den anden i hastighed. I både den rekursive og loop-variant summerer vi de samme tal. Men rekursionen involverer indlejrede kald og stak-håndtering. Det tager også ressourcer, så det er langsommere.
-P.P.S. Some engines support the "tail call" optimization: if a recursive call is the very last one in the function, with no other calculations performed, then the outer function will not need to resume the execution, so the engine doesn't need to remember its execution context. That removes the burden on memory. But if the JavaScript engine does not support tail call optimization (most of them don't), there will be an error: maximum stack size exceeded, because there's usually a limitation on the total stack size.
+P.P.S. Nogle motorer understøtter "tail call" optimering: hvis et rekursivt kald er det sidste i funktionen uden andre beregninger udført, så vil den ydre funktion ikke behøve at genoptage eksekveringen, så motoren behøver ikke at huske dens eksekveringskontekst. Det fjerner byrden på hukommelsen. Men hvis JavaScript-motoren ikke understøtter tail call optimering (de fleste gør ikke), vil der være en fejl: maksimal stakstørrelse overskredet, fordi der normalt er en begrænsning på den totale stakstørrelse.
diff --git a/1-js/06-advanced-functions/01-recursion/01-sum-to/task.md b/1-js/06-advanced-functions/01-recursion/01-sum-to/task.md
index cabc13290..9cd918675 100644
--- a/1-js/06-advanced-functions/01-recursion/01-sum-to/task.md
+++ b/1-js/06-advanced-functions/01-recursion/01-sum-to/task.md
@@ -2,11 +2,11 @@ importance: 5
---
-# Sum all numbers till the given one
+# Sammentæl alle tal op til et bestemt tal
-Write a function `sumTo(n)` that calculates the sum of numbers `1 + 2 + ... + n`.
+Skriv en funktion `sumTo(n)` som beregner summen af tallene `1 + 2 + ... + n`.
-For instance:
+For eksempel:
```js no-beautify
sumTo(1) = 1
@@ -17,20 +17,20 @@ sumTo(4) = 4 + 3 + 2 + 1 = 10
sumTo(100) = 100 + 99 + ... + 2 + 1 = 5050
```
-Make 3 solution variants:
+Opret tre variationer af løsningen:
-1. Using a for loop.
-2. Using a recursion, cause `sumTo(n) = n + sumTo(n-1)` for `n > 1`.
-3. Using the [arithmetic progression](https://en.wikipedia.org/wiki/Arithmetic_progression) formula.
+1. Ved brug af et `for`-loop.
+2. Ved brug af rekursion, da `sumTo(n) = n + sumTo(n-1)` for `n > 1`.
+3. Ved brug af formlen [Differensrække](https://da.wikipedia.org/wiki/Differensr%C3%A6kke). Det engelske opslag [aritmetisk progression](https://en.wikipedia.org/wiki/Arithmetic_progression) giver en dybere forklaring, hvis du har brug for det.
-An example of the result:
+Her er et eksempel på resultatet:
```js
-function sumTo(n) { /*... your code ... */ }
+function sumTo(n) { /*... din kode ... */ }
alert( sumTo(100) ); // 5050
```
-P.S. Which solution variant is the fastest? The slowest? Why?
+P.S. Hvilken løsning er hurtigst? Og hvilken er langsomst? Hvorfor?
-P.P.S. Can we use recursion to count `sumTo(100000)`?
+P.P.S. Kan vi bruge rekursion til at regne `sumTo(100000)`?
diff --git a/1-js/06-advanced-functions/01-recursion/02-factorial/solution.md b/1-js/06-advanced-functions/01-recursion/02-factorial/solution.md
index 09e511db5..245686be2 100644
--- a/1-js/06-advanced-functions/01-recursion/02-factorial/solution.md
+++ b/1-js/06-advanced-functions/01-recursion/02-factorial/solution.md
@@ -1,6 +1,6 @@
-By definition, a factorial `n!` can be written as `n * (n-1)!`.
+Grundlæggende kan fakultetet `n!` skrives som `n * (n-1)!`.
-In other words, the result of `factorial(n)` can be calculated as `n` multiplied by the result of `factorial(n-1)`. And the call for `n-1` can recursively descend lower, and lower, till `1`.
+Med andre ord kan resultatet af `factorial(n)` beregnes som `n` ganget med resultatet af `factorial(n-1)`. Og kaldet for `n-1` kan rekursivt falde ned, og ned, til `1`.
```js run
function factorial(n) {
@@ -10,7 +10,7 @@ function factorial(n) {
alert( factorial(5) ); // 120
```
-The basis of recursion is the value `1`. We can also make `0` the basis here, doesn't matter much, but gives one more recursive step:
+Basis af rekursion er tallet `1`. Vi kan også gøre `0` til basis her, det betyder ikke meget, men giver en ekstra rekursiv trin:
```js run
function factorial(n) {
diff --git a/1-js/06-advanced-functions/01-recursion/02-factorial/task.md b/1-js/06-advanced-functions/01-recursion/02-factorial/task.md
index d2aef2d90..ec77a33d6 100644
--- a/1-js/06-advanced-functions/01-recursion/02-factorial/task.md
+++ b/1-js/06-advanced-functions/01-recursion/02-factorial/task.md
@@ -2,17 +2,17 @@ importance: 4
---
-# Calculate factorial
+# Udregn faktorial
-The [factorial](https://en.wikipedia.org/wiki/Factorial) of a natural number is a number multiplied by `"number minus one"`, then by `"number minus two"`, and so on till `1`. The factorial of `n` is denoted as `n!`
+[Fakultet](https://da.wikipedia.org/wiki/Fakultet_(matematik))(engelsk [factorial](https://en.wikipedia.org/wiki/Factorial)) af et naturligt tal er tallet ganget med "tallet minus én", så med "tallet minus to", og så videre til `1`. Fakultetet af `n` betegnes som `n!`
-We can write a definition of factorial like this:
+Vi kan skrive en definition af fakultet som denne:
```js
n! = n * (n - 1) * (n - 2) * ...*1
```
-Values of factorials for different `n`:
+Værdier af fakultet for forskellige `n`:
```js
1! = 1
@@ -22,10 +22,10 @@ Values of factorials for different `n`:
5! = 5 * 4 * 3 * 2 * 1 = 120
```
-The task is to write a function `factorial(n)` that calculates `n!` using recursive calls.
+Opgaven er at skrive en funktion `factorial(n)` som beregner `n!` ved hjælp af rekursive kald.
```js
alert( factorial(5) ); // 120
```
-P.S. Hint: `n!` can be written as `n * (n-1)!` For instance: `3! = 3*2! = 3*2*1! = 6`
+Hint: `n!` kan skrives som `n * (n-1)!` For eksempel: `3! = 3*2! = 3*2*1! = 6`
diff --git a/1-js/06-advanced-functions/01-recursion/03-fibonacci-numbers/solution.md b/1-js/06-advanced-functions/01-recursion/03-fibonacci-numbers/solution.md
index 36524a45a..1aa05154a 100644
--- a/1-js/06-advanced-functions/01-recursion/03-fibonacci-numbers/solution.md
+++ b/1-js/06-advanced-functions/01-recursion/03-fibonacci-numbers/solution.md
@@ -1,6 +1,6 @@
-The first solution we could try here is the recursive one.
+Den første løsning vi kunne prøve er den rekursive.
-Fibonacci numbers are recursive by definition:
+Fibonacci-tallene er rekursive per definition:
```js run
function fib(n) {
@@ -9,14 +9,14 @@ function fib(n) {
alert( fib(3) ); // 2
alert( fib(7) ); // 13
-// fib(77); // will be extremely slow!
+// fib(77); // vil være meget langsom!
```
-...But for big values of `n` it's very slow. For instance, `fib(77)` may hang up the engine for some time eating all CPU resources.
+...Men for store værdier af `n` er det meget langsomt. For eksempel kan `fib(77)` få motoren til at hænge op i nogle sekunder og spise alle CPU-ressourcer.
-That's because the function makes too many subcalls. The same values are re-evaluated again and again.
+Det skyldes, at funktionen laver for mange underkald. De samme værdier evalueres igen og igen.
-For instance, let's see a piece of calculations for `fib(5)`:
+For eksempel, lad os se en del af beregningerne for `fib(5)`:
```js no-beautify
...
@@ -25,68 +25,68 @@ fib(4) = fib(3) + fib(2)
...
```
-Here we can see that the value of `fib(3)` is needed for both `fib(5)` and `fib(4)`. So `fib(3)` will be called and evaluated two times completely independently.
+Her kan vi se at `fib(3)` er nødvendig både for `fib(5)` og `fib(4)`. Så `fib(3)` vil blive kaldt og evalueret to gange helt uafhængigt.
-Here's the full recursion tree:
+Her er hele rekursions-træet:
-
+
-We can clearly notice that `fib(3)` is evaluated two times and `fib(2)` is evaluated three times. The total amount of computations grows much faster than `n`, making it enormous even for `n=77`.
+Vi kan tydeligt se at `fib(3)` evalueres to gange og `fib(2)` evalueres tre gange. Det samlede antal beregninger vokser meget hurtigere end `n`, hvilket gør det enormt endda for `n=77`.
-We can optimize that by remembering already-evaluated values: if a value of say `fib(3)` is calculated once, then we can just reuse it in future computations.
+Vi kan optimere det ved at huske allerede evaluerede værdier: hvis en værdi som f.eks. `fib(3)` beregnes én gang, så kan vi bare genbruge den i fremtidige beregninger.
-Another variant would be to give up recursion and use a totally different loop-based algorithm.
+En anden variant ville være at give op på rekursion og bruge et helt andet loop-baseret algoritme.
-Instead of going from `n` down to lower values, we can make a loop that starts from `1` and `2`, then gets `fib(3)` as their sum, then `fib(4)` as the sum of two previous values, then `fib(5)` and goes up and up, till it gets to the needed value. On each step we only need to remember two previous values.
+I stedet for at gå fra `n` og ned til lavere værdier kan vi oprette en løkke der starter fra `1` og `2`, så får vi `fib(3)` som summen af dem, så `fib(4)` som summen af de to foregående værdier, så `fib(5)` og går op og op, indtil det får den ønskede værdi. På hver trin behøver vi kun at huske de to foregående værdier.
-Here are the steps of the new algorithm in details.
+Her er trinene for den nye algoritme i detaljer.
-The start:
+Starten:
```js
-// a = fib(1), b = fib(2), these values are by definition 1
+// a = fib(1), b = fib(2), disse værdier er per definition 1
let a = 1, b = 1;
-// get c = fib(3) as their sum
+// Hent c = fib(3) som summen af dem
let c = a + b;
-/* we now have fib(1), fib(2), fib(3)
+/* nu har vi fib(1), fib(2), fib(3)
a b c
1, 1, 2
*/
```
-Now we want to get `fib(4) = fib(2) + fib(3)`.
+Nu vil vi gerne have fib(4) = fib(2) + fib(3)`.
-Let's shift the variables: `a,b` will get `fib(2),fib(3)`, and `c` will get their sum:
+Lad os skifte variablerne: `a,b` vil få `fib(2),fib(3)`, og `c` vil få deres sum:
```js no-beautify
-a = b; // now a = fib(2)
-b = c; // now b = fib(3)
+a = b; // nu a = fib(2)
+b = c; // nu b = fib(3)
c = a + b; // c = fib(4)
-/* now we have the sequence:
+/* nu har vi sekvensen:
a b c
1, 1, 2, 3
*/
```
-The next step gives another sequence number:
+Det næste trin giver endnu et nummer i sekvensen:
```js no-beautify
a = b; // now a = fib(3)
b = c; // now b = fib(4)
c = a + b; // c = fib(5)
-/* now the sequence is (one more number):
+/* nu er sekvensen:
a b c
1, 1, 2, 3, 5
*/
```
-...And so on until we get the needed value. That's much faster than recursion and involves no duplicate computations.
+...Og sådan fortsætter vi indtil vi får den ønskede værdi. Det er meget hurtigere end rekursion og involverer ingen duplikerede beregninger.
-The full code:
+Den fulde kode:
```js run
function fib(n) {
@@ -105,6 +105,6 @@ alert( fib(7) ); // 13
alert( fib(77) ); // 5527939700884757
```
-The loop starts with `i=3`, because the first and the second sequence values are hard-coded into variables `a=1`, `b=1`.
+Løkken starter med `i=3`, fordi de første to sekvensværdier er hardkodet i variablerne `a=1`, `b=1`.
-The approach is called [dynamic programming bottom-up](https://en.wikipedia.org/wiki/Dynamic_programming).
+Denne tilgang kaldes dynamisk programmering (på engelsk [dynamic programming bottom-up](https://en.wikipedia.org/wiki/Dynamic_programming)).
diff --git a/1-js/06-advanced-functions/01-recursion/03-fibonacci-numbers/task.md b/1-js/06-advanced-functions/01-recursion/03-fibonacci-numbers/task.md
index 3cdadd219..1572b6ec7 100644
--- a/1-js/06-advanced-functions/01-recursion/03-fibonacci-numbers/task.md
+++ b/1-js/06-advanced-functions/01-recursion/03-fibonacci-numbers/task.md
@@ -2,24 +2,24 @@ importance: 5
---
-# Fibonacci numbers
+# Fibonacci-tal
-The sequence of [Fibonacci numbers](https://en.wikipedia.org/wiki/Fibonacci_number) has the formula Fn = Fn-1 + Fn-2. In other words, the next number is a sum of the two preceding ones.
+Sekvensen af [Fibonacci-tal](https://da.wikipedia.org/wiki/Fibonacci-tal) (engelsk [Fibonacci numbers](https://en.wikipedia.org/wiki/Fibonacci_number)) har formlen Fn = Fn-1 + Fn-2. Med andre ord er det næste tal summen af de to foregående tal.
-First two numbers are `1`, then `2(1+1)`, then `3(1+2)`, `5(2+3)` and so on: `1, 1, 2, 3, 5, 8, 13, 21...`.
+Første to tal er `1`, så `2(1+1)`, så `3(1+2)`, `5(2+3)` og så videre: `1, 1, 2, 3, 5, 8, 13, 21...`.
-Fibonacci numbers are related to the [Golden ratio](https://en.wikipedia.org/wiki/Golden_ratio) and many natural phenomena around us.
+Fibonacci-tallene er relateret til [det gyldne snit](https://da.wikipedia.org/wiki/Det_gyldne_snit) (engelsk [Golden Ratio](https://en.wikipedia.org/wiki/Golden_ratio)) og mange naturlige fænomener omkring os.
-Write a function `fib(n)` that returns the `n-th` Fibonacci number.
+Skriv en funktion `fib(n)` som returnerer det `n-te` Fibonacci-tal.
-An example of work:
+Et eksempel på brug er:
```js
-function fib(n) { /* your code */ }
+function fib(n) { /* din kode */ }
alert(fib(3)); // 2
alert(fib(7)); // 13
alert(fib(77)); // 5527939700884757
```
-P.S. The function should be fast. The call to `fib(77)` should take no more than a fraction of a second.
+P.S. Funktionen skal være hurtig. Kaldet til `fib(77)` bør tage ikke mere end et sekund.
diff --git a/1-js/06-advanced-functions/01-recursion/04-output-single-linked-list/solution.md b/1-js/06-advanced-functions/01-recursion/04-output-single-linked-list/solution.md
index cfcbffea5..7f7741c31 100644
--- a/1-js/06-advanced-functions/01-recursion/04-output-single-linked-list/solution.md
+++ b/1-js/06-advanced-functions/01-recursion/04-output-single-linked-list/solution.md
@@ -1,6 +1,6 @@
-# Loop-based solution
+# Løkkebaseret løsning
-The loop-based variant of the solution:
+Den løkkebaserede variant af løsningen:
```js run
let list = {
@@ -30,7 +30,7 @@ function printList(list) {
printList(list);
```
-Please note that we use a temporary variable `tmp` to walk over the list. Technically, we could use a function parameter `list` instead:
+Bemærk venligst, at vi bruger en midlertidig variabel `tmp` til at gennemgå listen. Teknisk set kunne vi have brugt en funktionsparameter `list` i stedet:
```js
function printList(list) {
@@ -43,15 +43,15 @@ function printList(list) {
}
```
-...But that would be unwise. In the future we may need to extend a function, do something else with the list. If we change `list`, then we lose such ability.
+...Men det vil ikke være klog. I fremtiden kan vi have brug for at udvide en funktion, gøre noget andet med listen. Hvis vi ændrer `list`, så mister vi den evne.
-Talking about good variable names, `list` here is the list itself. The first element of it. And it should remain like that. That's clear and reliable.
+Når vi nu taler om gode variabelnavne, er `list` her listen selv. Det første element i den. Og det bør forblive som det er. Det er klart og pålideligt.
-From the other side, the role of `tmp` is exclusively a list traversal, like `i` in the `for` loop.
+Modsat er rollen for `tmp` udelukkende en midlertidig variabel til listetraversering, ligesom `i` i `for`-løkken.
-# Recursive solution
+# Rekursiv løsning
-The recursive variant of `printList(list)` follows a simple logic: to output a list we should output the current element `list`, then do the same for `list.next`:
+Den rekursive variant af `printList(list)` følger en simpel logik: for at udskrive en liste skal vi udskrive det nuværende element `list`, og derefter gøre det samme for `list.next`:
```js run
let list = {
@@ -70,10 +70,10 @@ let list = {
function printList(list) {
- alert(list.value); // output the current item
+ alert(list.value); // udskriver den aktuelle værdi
if (list.next) {
- printList(list.next); // do the same for the rest of the list
+ printList(list.next); // gør det samme for resten af listen
}
}
@@ -81,8 +81,8 @@ function printList(list) {
printList(list);
```
-Now what's better?
+Hvad er bedst?
-Technically, the loop is more effective. These two variants do the same, but the loop does not spend resources for nested function calls.
+Teknisk set er løkken mere effektiv. Disse to varianter gør det samme, men løkken bruger ikke ressourcer på indlejrede funktionskald.
-From the other side, the recursive variant is shorter and sometimes easier to understand.
+Modsat er den rekursive variant kortere og nogle gange lettere at forstå.
diff --git a/1-js/06-advanced-functions/01-recursion/04-output-single-linked-list/task.md b/1-js/06-advanced-functions/01-recursion/04-output-single-linked-list/task.md
index 1076b952a..f5404d936 100644
--- a/1-js/06-advanced-functions/01-recursion/04-output-single-linked-list/task.md
+++ b/1-js/06-advanced-functions/01-recursion/04-output-single-linked-list/task.md
@@ -2,9 +2,9 @@ importance: 5
---
-# Output a single-linked list
+# Udskriv en enkeltstrenget linked list
-Let's say we have a single-linked list (as described in the chapter ):
+Lad os sige, vi har en enkeltstrenget linked list (som beskrevet i kapitlet ):
```js
let list = {
@@ -22,8 +22,9 @@ let list = {
};
```
-Write a function `printList(list)` that outputs list items one-by-one.
+Skriv en funktion `printList(list)` som udskriver listens elementer ét ad gangen.
-Make two variants of the solution: using a loop and using recursion.
+Opret to varianter af løsningen: ved brug af en løkke og ved brug af rekursion.
+
+Hvad er bedst: med rekursion eller uden?
-What's better: with recursion or without it?
diff --git a/1-js/06-advanced-functions/01-recursion/05-output-single-linked-list-reverse/solution.md b/1-js/06-advanced-functions/01-recursion/05-output-single-linked-list-reverse/solution.md
index 0eb76ea1c..a43b6d7c4 100644
--- a/1-js/06-advanced-functions/01-recursion/05-output-single-linked-list-reverse/solution.md
+++ b/1-js/06-advanced-functions/01-recursion/05-output-single-linked-list-reverse/solution.md
@@ -1,8 +1,8 @@
-# Using a recursion
+# Ved brug af rekursion
-The recursive logic is a little bit tricky here.
+Den recursive logik er en lille smule svær her.
-We need to first output the rest of the list and *then* output the current one:
+Vi skal først udskrive resten af listen og *derefter* udskrive det nuværende element:
```js run
let list = {
@@ -31,13 +31,13 @@ function printReverseList(list) {
printReverseList(list);
```
-# Using a loop
+# Ved brug af en løkke
-The loop variant is also a little bit more complicated than the direct output.
+Den løkkebaserede variant er også en lille smule mere kompliceret end direkte output.
-There is no way to get the last value in our `list`. We also can't "go back".
+Der er ingen måde at få den sidste værdi i vores `list`. Vi kan også ikke "gå tilbage".
-So what we can do is to first go through the items in the direct order and remember them in an array, and then output what we remembered in the reverse order:
+Få det vi kan gøre er at gennemgå elementerne i den direkte rækkefølge og huske dem i et array, og derefter udskrive det vi huskede i omvendt rækkefølge:
```js run
let list = {
@@ -71,4 +71,4 @@ function printReverseList(list) {
printReverseList(list);
```
-Please note that the recursive solution actually does exactly the same: it follows the list, remembers the items in the chain of nested calls (in the execution context stack), and then outputs them.
+Bemærk at den rekursive løsning gør præcis det samme: den følger listen, husker elementerne i kæden af indlejrede kald (i eksekveringsstakken), og udskriver dem derefter.
diff --git a/1-js/06-advanced-functions/01-recursion/05-output-single-linked-list-reverse/task.md b/1-js/06-advanced-functions/01-recursion/05-output-single-linked-list-reverse/task.md
index 81b1f3e33..be4b40529 100644
--- a/1-js/06-advanced-functions/01-recursion/05-output-single-linked-list-reverse/task.md
+++ b/1-js/06-advanced-functions/01-recursion/05-output-single-linked-list-reverse/task.md
@@ -2,8 +2,8 @@ importance: 5
---
-# Output a single-linked list in the reverse order
+# Udskriv en enkeltstrenget linked list i omvendt rækkefølge
-Output a single-linked list from the previous task in the reverse order.
+Udskriv en enkeltstrenget linked list fra det forrige opgave i omvendt rækkefølge.
-Make two solutions: using a loop and using a recursion.
+Lav to løsninger: ved brug af en løkke og ved brug af rekursion.
diff --git a/1-js/06-advanced-functions/01-recursion/article.md b/1-js/06-advanced-functions/01-recursion/article.md
index 5ae894474..9bfe856f2 100644
--- a/1-js/06-advanced-functions/01-recursion/article.md
+++ b/1-js/06-advanced-functions/01-recursion/article.md
@@ -1,18 +1,18 @@
-# Recursion and stack
+# Rekursion og stak
-Let's return to functions and study them more in-depth.
+Lad os vende tilbage til funktioner og studere dem mere grundigt.
-Our first topic will be *recursion*.
+Vores første emne vil være *rekursion*.
-If you are not new to programming, then it is probably familiar and you could skip this chapter.
+Hvis du ikke er ny i programmering, så er det sandsynligvis kendt og du kan springe dette kapitel over.
-Recursion is a programming pattern that is useful in situations when a task can be naturally split into several tasks of the same kind, but simpler. Or when a task can be simplified into an easy action plus a simpler variant of the same task. Or, as we'll see soon, to deal with certain data structures.
+Rekursion er et programmeringsmønster, som er nyttigt i situationer hvor en opgave kan opdeles i flere opgaver af samme type, men mere simple. Eller når en opgave kan formindskes til en enkel handling plus en mere simpel variant af samme opgave. Eller, som vi vil se snart, for at håndtere bestemte datastrukturer.
-When a function solves a task, in the process it can call many other functions. A partial case of this is when a function calls *itself*. That's called *recursion*.
+Når en funktion løser en opgave, kan den i processen kalde mange andre funktioner. En delmængde heraf er når en funktion kalder *sig selv*. Det kaldes *rekursion*.
-## Two ways of thinking
+## To måder at tænke på
-For something simple to start with -- let's write a function `pow(x, n)` that raises `x` to a natural power of `n`. In other words, multiplies `x` by itself `n` times.
+For noget simpelt at starte med -- lad os skrive en funktion `pow(x, n)` som hæver `x` til en naturlig potens af `n`. Med andre ord, multiplicerer `x` med sig selv `n` gange.
```js
pow(2, 2) = 4
@@ -20,15 +20,15 @@ pow(2, 3) = 8
pow(2, 4) = 16
```
-There are two ways to implement it.
+Der er to måder at implementere det.
-1. Iterative thinking: the `for` loop:
+1. Iterativ tankegang: `for`-loopet:
```js run
function pow(x, n) {
let result = 1;
- // multiply result by x n times in the loop
+ // Gang resultatet med x n gange i loopet
for (let i = 0; i < n; i++) {
result *= x;
}
@@ -39,7 +39,7 @@ There are two ways to implement it.
alert( pow(2, 3) ); // 8
```
-2. Recursive thinking: simplify the task and call self:
+2. Rekursiv tænkning: Simplificer opgaven og kald dig selv:
```js run
function pow(x, n) {
@@ -53,9 +53,9 @@ There are two ways to implement it.
alert( pow(2, 3) ); // 8
```
-Please note how the recursive variant is fundamentally different.
+Bemærk hvordan den rekursive variant er grundiglæggende anderledes.
-When `pow(x, n)` is called, the execution splits into two branches:
+Når `pow(x, n)` kaldes splittes udførelsen til to forgreninger:
```js
if n==1 = x
@@ -65,27 +65,27 @@ pow(x, n) =
else = x * pow(x, n - 1)
```
-1. If `n == 1`, then everything is trivial. It is called *the base* of recursion, because it immediately produces the obvious result: `pow(x, 1)` equals `x`.
-2. Otherwise, we can represent `pow(x, n)` as `x * pow(x, n - 1)`. In maths, one would write xn = x * xn-1. This is called *a recursive step*: we transform the task into a simpler action (multiplication by `x`) and a simpler call of the same task (`pow` with lower `n`). Next steps simplify it further and further until `n` reaches `1`.
+1. Hvis `n == 1`, så er alt trivielt. Dette kaldes *basen* for rekursion, fordi den fordi den umiddelbart producerer det obviouse resultat: `pow(x, 1)` er lig med `x`.
+2. Ellers kan vi repræsentere `pow(x, n)` som `x * pow(x, n - 1)`. I matematik ville man skrive xn = x * xn-1. Dette kaldes *et rekursivt trin*: vi transformerer opgaven til en enkel handling (multiplication med `x`) og et mere simpelt kald af samme opgave (`pow` med lavere `n`). Næste trin forenkler det yderligere og yderligere indtil `n` når `1`.
-We can also say that `pow` *recursively calls itself* till `n == 1`.
+Vi kan også sige at `pow` *kalder sig selv rekursivt* indtil `n == 1`.
-
+
-For example, to calculate `pow(2, 4)` the recursive variant does these steps:
+For eksempel, for at udregne `pow(2, 4)` vil den rekursive variant gøre disse trin:
1. `pow(2, 4) = 2 * pow(2, 3)`
2. `pow(2, 3) = 2 * pow(2, 2)`
3. `pow(2, 2) = 2 * pow(2, 1)`
4. `pow(2, 1) = 2`
-So, the recursion reduces a function call to a simpler one, and then -- to even more simpler, and so on, until the result becomes obvious.
+så rekursionen reducerer et funktionskald til et mere simpelt, og så videre, indtil resultatet bliver åbenlyst.
-````smart header="Recursion is usually shorter"
-A recursive solution is usually shorter than an iterative one.
+````smart header="Rekursion er normalt kortere"
+En rekursiv løsning er normalt kortere end en iterativ.
-Here we can rewrite the same using the conditional operator `?` instead of `if` to make `pow(x, n)` more terse and still very readable:
+Her kan vi omskrive det samme med betingelsesoperatoren `?` i stedet for `if` for at gøre `pow(x, n)` mere kompakt og stadig meget læselig:
```js run
function pow(x, n) {
@@ -94,36 +94,36 @@ function pow(x, n) {
```
````
-The maximal number of nested calls (including the first one) is called *recursion depth*. In our case, it will be exactly `n`.
+Det maksimalt antal indlejrede kald (inklusive det første) kaldes *rekursionsdybde*. I vores tilfælde vil det være præcis `n`.
-The maximal recursion depth is limited by JavaScript engine. We can rely on it being 10000, some engines allow more, but 100000 is probably out of limit for the majority of them. There are automatic optimizations that help alleviate this ("tail calls optimizations"), but they are not yet supported everywhere and work only in simple cases.
+Den maksimale rekursionsdybde er begrænset af JavaScript-motoren. Vi kan stole på, at den er 10.000, nogle motorer tillader mere, men 100.000 er sandsynligvis uden for grænsen for de fleste af dem. Der er automatiske optimeringer, der hjælper med at optimere antallet af kald ("tail calls optimizations"), men de er ikke endnu understøttet overalt og virker kun i simple tilfælde.
-That limits the application of recursion, but it still remains very wide. There are many tasks where recursive way of thinking gives simpler code, easier to maintain.
+Det begrænser anvendelsen af rekursion, men den forbliver stadig meget bred. Der er mange opgaver hvor den rekursive måde at tænke giver enklere kode der er nemmere at vedligeholde.
-## The execution context and stack
+## Eksekveringens kontekst og stak
-Now let's examine how recursive calls work. For that we'll look under the hood of functions.
+Lad os undersøge hvordan rekursive kald fungerer. For det vil vi kigge under huden på funktioner.
-The information about the process of execution of a running function is stored in its *execution context*.
+Informationen om processen for eksekvering af en kørende funktion er gemt i dens *eksekveringskontekst*.
-The [execution context](https://tc39.github.io/ecma262/#sec-execution-contexts) is an internal data structure that contains details about the execution of a function: where the control flow is now, the current variables, the value of `this` (we don't use it here) and few other internal details.
+[Eksekveringskonteksten](https://tc39.github.io/ecma262/#sec-execution-contexts) er en intern datastruktur, der indeholder detaljer om eksekveringen af en funktion: hvor kontrolløbet er nu, de aktuelle variabler, værdien af `this` (vi bruger det ikke her) og andre interne detaljer.
-One function call has exactly one execution context associated with it.
+Et funktionskald har præcis én eksekveringskontekst forbundet med det.
-When a function makes a nested call, the following happens:
+Når en funktion udfører et indlejret kald, sker følgende:
-- The current function is paused.
-- The execution context associated with it is remembered in a special data structure called *execution context stack*.
-- The nested call executes.
-- After it ends, the old execution context is retrieved from the stack, and the outer function is resumed from where it stopped.
+- Den nuværende funktion pauses.
+- Den eksekveringskontekst, der er forbundet med den, huskes i en speciel datastruktur kaldet *execution context stack*.
+- Det indlejrede kald udføres.
+- Når det er færdigt, hentes den gamle eksekveringskontekst fra stakken og den ydre funktion genoptages fra hvor den stoppede.
-Let's see what happens during the `pow(2, 3)` call.
+Lad os se hvad der sker under kaldet `pow(2, 3)`.
### pow(2, 3)
-In the beginning of the call `pow(2, 3)` the execution context will store variables: `x = 2, n = 3`, the execution flow is at line `1` of the function.
+I begyndelsen af kaldet `pow(2, 3)` vil eksekveringskonteksten gemme variablerne: `x = 2, n = 3`, og kontrolløbet er på linje `1` i funktionen.
-We can sketch it as:
+Vi kan skitsere det som:
@@ -132,7 +132,7 @@ We can sketch it as:
-That's when the function starts to execute. The condition `n == 1` is falsy, so the flow continues into the second branch of `if`:
+Det er her funktionen begynder at eksekvere. Betingelsen `n == 1` er falsk, så flowet fortsætter til den anden gren af `if`:
```js run
function pow(x, n) {
@@ -149,7 +149,7 @@ alert( pow(2, 3) );
```
-The variables are same, but the line changes, so the context is now:
+Variablene er de samme, men linjen ændres, så konteksten er nu:
@@ -158,67 +158,67 @@ The variables are same, but the line changes, so the context is now:
-To calculate `x * pow(x, n - 1)`, we need to make a subcall of `pow` with new arguments `pow(2, 2)`.
+For at udregne `x * pow(x, n - 1)`, vi skal lave et indlejret kald af `pow` med nye argumenter `pow(2, 2)`.
### pow(2, 2)
-To do a nested call, JavaScript remembers the current execution context in the *execution context stack*.
+For at udføre et indlejret kald, husker JavaScript den nuværende eksekveringskontekst i *execution context stack*.
-Here we call the same function `pow`, but it absolutely doesn't matter. The process is the same for all functions:
+Her kalder vi den samme funktion `pow`, men det spiller ingen rolle. Processen er den samme for alle funktioner:
-1. The current context is "remembered" on top of the stack.
-2. The new context is created for the subcall.
-3. When the subcall is finished -- the previous context is popped from the stack, and its execution continues.
+1. Den nuværende kontekst huskes øverst på stakken.
+2. En ny kontekst oprettes for underkaldet.
+3. Når underkaldet er færdigt -- bliver den gamle kontekst fjernet fra stakken, og dens eksekvering genoptages.
-Here's the context stack when we entered the subcall `pow(2, 2)`:
+Her er kontekststakken efter vi er gået ind i underkaldet `pow(2, 2)`:
- Context: { x: 2, n: 2, at line 1 }
+ Kontekst: { x: 2, n: 2, at line 1 }pow(2, 2)
- Context: { x: 2, n: 3, at line 5 }
+ Kontekst: { x: 2, n: 3, at line 5 }pow(2, 3)
-The new current execution context is on top (and bold), and previous remembered contexts are below.
+Den nye nuværende eksekveringskontekst er øverst (og fed), og de tidligere huskede kontekster er nedenfor.
-When we finish the subcall -- it is easy to resume the previous context, because it keeps both variables and the exact place of the code where it stopped.
+Når underkaldet er færdigt -- er det nemt at genoptage den gamle kontekst, fordi den beholder både variablerne og den præcise sted i koden hvor den stoppede.
```smart
-Here in the picture we use the word "line", as in our example there's only one subcall in line, but generally a single line of code may contain multiple subcalls, like `pow(…) + pow(…) + somethingElse(…)`.
+Her i billedet bruger vi ordet "line", som i vores eksempel er der kun ét underkald i en linje, men generelt kan en enkelt linje af kode indeholde flere underkald, f.eks. `pow(…) + pow(…) + somethingElse(…)`.
-So it would be more precise to say that the execution resumes "immediately after the subcall".
+Så det ville være mere præcist at sige, at eksekveringen genoptages "øjeblikkeligt efter underkaldet".
```
### pow(2, 1)
-The process repeats: a new subcall is made at line `5`, now with arguments `x=2`, `n=1`.
+Processen gentages: et nyt underkald oprettes på linje `5`, nu med argumenterne `x=2`, `n=1`.
-A new execution context is created, the previous one is pushed on top of the stack:
+En ny eksekveringskontekst oprettes, den gamle kontekst bliver pushed øverst på stakken:
- Context: { x: 2, n: 1, at line 1 }
+ Kontekst: { x: 2, n: 1, at line 1 }pow(2, 1)
- Context: { x: 2, n: 2, at line 5 }
+ Kontekst: { x: 2, n: 2, at line 5 }pow(2, 2)
- Context: { x: 2, n: 3, at line 5 }
+ Kontekst: { x: 2, n: 3, at line 5 }pow(2, 3)
-There are 2 old contexts now and 1 currently running for `pow(2, 1)`.
+Der er 2 gamle kontekster og 1 nuværende kontekst for `pow(2, 1)`.
-### The exit
+### Udgangen
-During the execution of `pow(2, 1)`, unlike before, the condition `n == 1` is truthy, so the first branch of `if` works:
+Med udførelsen af `pow(2, 1)` vil betingelsen `n == 1`, i modsætning til før, være sand. Derfor udføres den første gren af `if`:
```js
function pow(x, n) {
@@ -232,9 +232,9 @@ function pow(x, n) {
}
```
-There are no more nested calls, so the function finishes, returning `2`.
+Der er ikke flere indlejrede kald, så funktionen afslutter og returnerer `2`.
-As the function finishes, its execution context is not needed anymore, so it's removed from the memory. The previous one is restored off the top of the stack:
+Når funktionen afslutter, er dens eksekveringskontekst ikke længere nødvendig, så den fjernes fra hukommelsen. Den tidligere kontekst genoprettes fra toppen af stakken:
@@ -248,26 +248,26 @@ As the function finishes, its execution context is not needed anymore, so it's r
-The execution of `pow(2, 2)` is resumed. It has the result of the subcall `pow(2, 1)`, so it also can finish the evaluation of `x * pow(x, n - 1)`, returning `4`.
+Udførelsen af `pow(2, 2)` genoptages. Den har resultatet af underkaldet `pow(2, 1)`, så den også kan færdiggøre evalueringen af `x * pow(x, n - 1)`, og returnere `4`.
-Then the previous context is restored:
+Så den tidligere kontekst genoprettes:
- Context: { x: 2, n: 3, at line 5 }
+ Kontekst: { x: 2, n: 3, at line 5 }pow(2, 3)
-When it finishes, we have a result of `pow(2, 3) = 8`.
+Når den afslutter, har vi et resultat på `pow(2, 3) = 8`.
-The recursion depth in this case was: **3**.
+Dybden af rekursionen i dette tilfælde var: **3**.
-As we can see from the illustrations above, recursion depth equals the maximal number of context in the stack.
+Som vi kan se fra illustrationerne ovenfor, er rekursionsdybden lig med det maksimale antal kontekster i stakken.
-Note the memory requirements. Contexts take memory. In our case, raising to the power of `n` actually requires the memory for `n` contexts, for all lower values of `n`.
+Bemærk hukommelseskravene. Kontekster tager plads. I vores tilfælde kræver en udregning til potens af `n` faktisk hukommelse for `n` kontekster, for alle lavere værdier af `n`.
-A loop-based algorithm is more memory-saving:
+En algoritme baseret på løkker er mere hukommelsesvenlig:
```js
function pow(x, n) {
@@ -281,19 +281,19 @@ function pow(x, n) {
}
```
-The iterative `pow` uses a single context changing `i` and `result` in the process. Its memory requirements are small, fixed and do not depend on `n`.
+Denne udgave af `pow` bruger kun en enkelt kontekst der ændrer `i` og `result` i processen. Dens hukommelseskrav er små, faste og afhænger ikke af `n`.
-**Any recursion can be rewritten as a loop. The loop variant usually can be made more effective.**
+**Enhver rekursion kan omskrives som en løkke. Versionen baseret på løkker er ofte mere effektiv.**
-...But sometimes the rewrite is non-trivial, especially when a function uses different recursive subcalls depending on conditions and merges their results or when the branching is more intricate. And the optimization may be unneeded and totally not worth the efforts.
+...men nogle gange er omskrivningen ikke-triviel, især når en funktion bruger forskellige rekursive underkald afhængigt af betingelser og fletter deres resultater eller når forgreningen er mere kompleks. Endelig kan optimeringen være unødvendig til en grad hvor det ikke er værd værd at investere i.
-Recursion can give a shorter code, easier to understand and support. Optimizations are not required in every place, mostly we need a good code, that's why it's used.
+Rekursion kan give en kortere kode der nemmere at forstå og understøtte. Optimeringer er ikke nødvendige overalt. Det vigtigste vi har brug for er god kode, og her kan rekursion være at foretrække (når man har "knækket koden" il at forstå den).
-## Recursive traversals
+## Rekursive 'traversals'
-Another great application of the recursion is a recursive traversal.
+Et anden god brug af rekursion er rekursive 'traversal'. Jeg tror ikke der er et godt direkte dansk ord, men det betyder noget i stil med *gennemløb af alle elementer i en struktur*.
-Imagine, we have a company. The staff structure can be presented as an object:
+Forestil dig et firma. I det kan medarbejdernes struktureres i et objekt i stil med dette:
```js
let company = {
@@ -322,34 +322,34 @@ let company = {
};
```
-In other words, a company has departments.
+Med andre ord - et firma har afdelinger.
-- A department may have an array of staff. For instance, `sales` department has 2 employees: John and Alice.
-- Or a department may split into subdepartments, like `development` has two branches: `sites` and `internals`. Each of them has their own staff.
-- It is also possible that when a subdepartment grows, it divides into subsubdepartments (or teams).
+- En afdeling kan have et array af medarbejdere. For eksempel har salgsafdelingen (`sales`) 2 medarbejdere: John og Alice.
+- Eller en afdeling kan opdeles i underafdelinger, som `development` har to grene: `sites` og `internals`. Hver af dem har deres egen medarbejderliste.
+- Det er også muligt at en underafdeling vokser og opdeles i underunderafdelinger (eller hold).
- For instance, the `sites` department in the future may be split into teams for `siteA` and `siteB`. And they, potentially, can split even more. That's not on the picture, just something to have in mind.
+ For eksempel kan `sites`-afdelingen i fremtiden opdeles i hold for `siteA` og `siteB`. Og de, potentielt, kan opdeles end mere. Det er ikke på billedet, bare noget at have i tankerne.
-Now let's say we want a function to get the sum of all salaries. How can we do that?
+Lad os nu forestille os at vi vil have en funktion der lægger alle lønninger (salaries) sammen. Hvordan gør vi det?
-An iterative approach is not easy, because the structure is not simple. The first idea may be to make a `for` loop over `company` with nested subloop over 1st level departments. But then we need more nested subloops to iterate over the staff in 2nd level departments like `sites`... And then another subloop inside those for 3rd level departments that might appear in the future? If we put 3-4 nested subloops in the code to traverse a single object, it becomes rather ugly.
+En iterativ tilgang er ikke nem da strukturen ikke er simpel. En første idé kunne være at gennemløbe `company` med en nested subloop over 1. niveau afdelinger. Men så skal vi have flere nested subloops for at gennemløbe medarbejderne i 2. niveau afdelinger som `sites`... Og så en subloop inden i dem for 3. niveau afdelinger som måske vil opstå i fremtiden? Hvis vi sætter 3-4 nested subloops i koden for at gennemløbe et enkelt objekt, bliver det ret hurtigt svært at håndtere.
-Let's try recursion.
+Lad os prøve rekursion.
-As we can see, when our function gets a department to sum, there are two possible cases:
+Som vi kan se, når vores funktion får en afdeling den skal sammentælle, er der to mulige tilfælde:
-1. Either it's a "simple" department with an *array* of people -- then we can sum the salaries in a simple loop.
-2. Or it's *an object* with `N` subdepartments -- then we can make `N` recursive calls to get the sum for each of the subdeps and combine the results.
+1. Enten er den en "simpel" afdeling med et *array* af medarbejdere -- da kan vi summe lønningerne i en simpel loop.
+2. Eller den er *et objekt* med `N` underafdelinger -- da kan vi lave `N` rekursive kald for at få summen for hver af de underafdelinger og kombinere resultaterne.
-The 1st case is the base of recursion, the trivial case, when we get an array.
+Det første tilfælde er basen for rekursionen, det trivielle tilfælde, når vi får et array.
-The 2nd case when we get an object is the recursive step. A complex task is split into subtasks for smaller departments. They may in turn split again, but sooner or later the split will finish at (1).
+Det andet tilfælde når vi får et objekt er det rekursive trin. En kompleks opgave opdeles i underopgaver for mindre afdelinger. De kan i sin tur opdeles igen, men snarest eller senest vil opdeltningen slutte ved (1).
-The algorithm is probably even easier to read from the code:
+Algoritmen er sandsynligvis endnu lettere at læse fra koden:
```js run
-let company = { // the same object, compressed for brevity
+let company = { // det samme objekt, komprimeret
sales: [{name: 'John', salary: 1000}, {name: 'Alice', salary: 1600 }],
development: {
sites: [{name: 'Peter', salary: 2000}, {name: 'Alex', salary: 1800 }],
@@ -357,15 +357,15 @@ let company = { // the same object, compressed for brevity
}
};
-// The function to do the job
+// Funktionen der udfører jobbet
*!*
function sumSalaries(department) {
- if (Array.isArray(department)) { // case (1)
+ if (Array.isArray(department)) { // Tilfælde (1)
return department.reduce((prev, current) => prev + current.salary, 0); // sum the array
- } else { // case (2)
+ } else { // Tilfælde (2)
let sum = 0;
for (let subdep of Object.values(department)) {
- sum += sumSalaries(subdep); // recursively call for subdepartments, sum the results
+ sum += sumSalaries(subdep); // rekursivt kald til underafdelinger. Sammentæl alle deres returnerede resultater
}
return sum;
}
@@ -375,62 +375,62 @@ function sumSalaries(department) {
alert(sumSalaries(company)); // 7700
```
-The code is short and easy to understand (hopefully?). That's the power of recursion. It also works for any level of subdepartment nesting.
+Koden er kort og (forhåbentlig) nem at forstå. Det er kraften i rekursionen. Den virker også for ethvert niveau af underafdelingsindlejring.
-Here's the diagram of calls:
+Her er et diagram over kaldene:
-
+
-We can easily see the principle: for an object `{...}` subcalls are made, while arrays `[...]` are the "leaves" of the recursion tree, they give immediate result.
+Her kan vi måske nemmere se principperne: for et objekt `{...}` udføres subkald, mens arrays `[...]` er "blade" i rekursions-træet og giver umiddelbare resultater.
-Note that the code uses smart features that we've covered before:
+Bemærk at koden bruger et par af de smarte muligheder som vi har gennemgået tidligere:
-- Method `arr.reduce` explained in the chapter to get the sum of the array.
-- Loop `for(val of Object.values(obj))` to iterate over object values: `Object.values` returns an array of them.
+- Metoden `arr.reduce` forklaret i kapitlet returnerer summen af et array.
+- Løkken `for(val of Object.values(obj))` itererer over et objekt og `Object.values` returnerer et array af dens værdier.
-## Recursive structures
+## Rekursive strukturer
-A recursive (recursively-defined) data structure is a structure that replicates itself in parts.
+En rekursiv (recursivt defineret) datastruktur er en struktur der replikerer sig selv i dele.
-We've just seen it in the example of a company structure above.
+Vi har lige set det i eksemplet med en virksomhedsstruktur ovenfor.
-A company *department* is:
-- Either an array of people.
-- Or an object with *departments*.
+En virksomheds *afdeling* er:
+- Enten et array af medarbejdere.
+- Eller et objekt med *underafdelinger*.
-For web-developers there are much better-known examples: HTML and XML documents.
+For webudviklere er der et meget mere velkendt eksempel: HTML og XML dokumenter.
-In the HTML document, an *HTML-tag* may contain a list of:
-- Text pieces.
-- HTML-comments.
-- Other *HTML-tags* (that in turn may contain text pieces/comments or other tags etc).
+I et HTML dokument kan et *HTML-tag* indeholde en liste af:
+- Tekststykker.
+- HTML-kommentarer.
+- Andre *HTML-tags* (der i sig selv kan indeholde tekststykker/kommentarer eller andre tags etc).
-That's once again a recursive definition.
+Det er igen en rekursiv definition.
-For better understanding, we'll cover one more recursive structure named "Linked list" that might be a better alternative for arrays in some cases.
+For bedre at forstå dette vil vi gennemgå en mere kompleks rekursiv struktur kaldet "Linked list" som kan være en bedre alternativ til arrays i nogle tilfælde.
### Linked list
-Imagine, we want to store an ordered list of objects.
+Forestil dig, vi vil gemme en ordnet liste af objekter.
-The natural choice would be an array:
+Den naturlige valg er et array:
```js
let arr = [obj1, obj2, obj3];
```
-...But there's a problem with arrays. The "delete element" and "insert element" operations are expensive. For instance, `arr.unshift(obj)` operation has to renumber all elements to make room for a new `obj`, and if the array is big, it takes time. Same with `arr.shift()`.
+...Men der er et problem med arrays. Operationerne "slet element" og "indsæt element" er dyre. For eksempel vil `arr.unshift(obj)` være nødt til at renummerere alle elementer for at skabe plads for det nye element `obj`. Hvis det er et stort array, så tager det tid; det samme vil ske med `arr.shift()`.
-The only structural modifications that do not require mass-renumbering are those that operate with the end of array: `arr.push/pop`. So an array can be quite slow for big queues, when we have to work with the beginning.
+Den eneste modifikation der ikke kræver masser af renummerering er de operationer der arbejder med slutningen af arrayet: `arr.push/pop`. Så et array kan være ret langsomt for store køer, når vi skal arbejde med starten.
-Alternatively, if we really need fast insertion/deletion, we can choose another data structure called a [linked list](https://en.wikipedia.org/wiki/Linked_list).
+Alternativt, hvis vi virkelig har brug for hurtig indsættelse/sletning, kan vi vælge en anden datastruktur kaldet en [linked list](https://en.wikipedia.org/wiki/Linked_list).
-The *linked list element* is recursively defined as an object with:
-- `value`.
-- `next` property referencing the next *linked list element* or `null` if that's the end.
+Et *linked list element* er rekursivt defineret som et objekt med:
+- `value` - værdien af elementet.
+- `next` - en reference til det næste *linked list element* eller `null` hvis det er slutningen.
-For instance:
+For eksempel er her en linked list med 4 elementer:
```js
let list = {
@@ -448,11 +448,11 @@ let list = {
};
```
-Graphical representation of the list:
+Her er en grafisk repræsentation af listen:

-An alternative code for creation:
+En alternativ kode for oprettelse af den samme linked list kunne være:
```js no-beautify
let list = { value: 1 };
@@ -462,9 +462,9 @@ list.next.next.next = { value: 4 };
list.next.next.next.next = null;
```
-Here we can even more clearly see that there are multiple objects, each one has the `value` and `next` pointing to the neighbour. The `list` variable is the first object in the chain, so following `next` pointers from it we can reach any element.
+Her kan vi tydeligere se at der er flere objekter, hvor hvert objekt har `value` og `next` som peger på naboen. Variablen `list` er det første objekt i kæden, så ved at følge `next`-pegerne fra det kan vi nå ethvert element.
-The list can be easily split into multiple parts and later joined back:
+Listen kan nemt opdeles i flere dele og senere genoprettes:
```js
let secondList = list.next.next;
@@ -473,15 +473,15 @@ list.next.next = null;

-To join:
+For at genoprette den oprindelige liste, skal vi bare forbinde den første del med den anden:
```js
list.next.next = secondList;
```
-And surely we can insert or remove items in any place.
+Og vi kan indsætte eller fjerne elementer hvor som helst.
-For instance, to prepend a new value, we need to update the head of the list:
+For eksempel, for at indsætte et nyt element i starten af listen, skal vi opdatere hovedet af listen:
```js
let list = { value: 1 };
@@ -490,14 +490,14 @@ list.next.next = { value: 3 };
list.next.next.next = { value: 4 };
*!*
-// prepend the new value to the list
+// indsæt et nyt element i starten af listen
list = { value: "new item", next: list };
*/!*
```

-To remove a value from the middle, change `next` of the previous one:
+For at fjerne et element fra midten, ændre `next` af det forrige element:
```js
list.next = list.next.next;
@@ -505,38 +505,38 @@ list.next = list.next.next;

-We made `list.next` jump over `1` to value `2`. The value `1` is now excluded from the chain. If it's not stored anywhere else, it will be automatically removed from the memory.
+Her får vi `list.next` til at hoppe over `1` til værdien `2`. Værdien `1` er nu fjernet fra kæden. Hvis den ikke er gemt et andet sted, vil den automatisk blive fjernet fra hukommelsen.
-Unlike arrays, there's no mass-renumbering, we can easily rearrange elements.
+I modsætning til arrays sker der ingen massiv omnummerering, vi kan nemt rearrangere elementer.
-Naturally, lists are not always better than arrays. Otherwise everyone would use only lists.
+Naturligvis er denne slags lister ikke altid bedre end arrays. Ellers ville alle bruge kun lister.
-The main drawback is that we can't easily access an element by its number. In an array that's easy: `arr[n]` is a direct reference. But in the list we need to start from the first item and go `next` `N` times to get the Nth element.
+Den store ulempe er at vi ikke nemt kan tilgå et element ved dets nummer. I et array er det nemt: `arr[n]` er en direkte reference. Men i listen skal vi starte fra det første element og gå `next` `N` gange for at nå det N'te element.
-...But we don't always need such operations. For instance, when we need a queue or even a [deque](https://en.wikipedia.org/wiki/Double-ended_queue) -- the ordered structure that must allow very fast adding/removing elements from both ends, but access to its middle is not needed.
+...Men vi har ikke altid brug for sådanne operationer. For eksempel, når vi har brug for en kø eller endda en [deque](https://en.wikipedia.org/wiki/Double-ended_queue) -- den ordnede struktur der skal tillade meget hurtigt tilføjelse/fjernelse af elementer fra begge ender, men adgang til midten ikke er nødvendig.
-Lists can be enhanced:
-- We can add property `prev` in addition to `next` to reference the previous element, to move back easily.
-- We can also add a variable named `tail` referencing the last element of the list (and update it when adding/removing elements from the end).
-- ...The data structure may vary according to our needs.
+Lister kan forbedres:
+- Vi kan tilføje en egenskab `prev` i tilføjelse til `next` for at referere til det forrige element, så man nemt kan gå baglæns.
+- Vi kan også tilføje en variabel kaldet `tail` som refererer til det sidste element i listen (og opdatere den når man tilføjer/fjerner elementer fra slutningen).
+- ...Datastrukturen kan justeres i forhold til specifikke behov.
-## Summary
+## Opsummering
Terms:
-- *Recursion* is a programming term that means calling a function from itself. Recursive functions can be used to solve tasks in elegant ways.
+- *Rekursion* er et begreb i programmering der henviser til at en funktion kalder sig selv. Rekursive funktioner kan bruges til at løse opgaver på en elegant måde.
- When a function calls itself, that's called a *recursion step*. The *basis* of recursion is function arguments that make the task so simple that the function does not make further calls.
+ Når en funktion kalder sig selv, kaldes det et *rekursions-trin*. *Basis* for rekursion er funktionsargumenter, der gør opgaven så simpel, at funktionen ikke laver yderligere kald til sig selv.
-- A [recursively-defined](https://en.wikipedia.org/wiki/Recursive_data_type) data structure is a data structure that can be defined using itself.
+- En [recursivt defineret](https://en.wikipedia.org/wiki/Recursive_data_type) datastruktur er en datastruktur der kan defineres ved hjælp af sig selv.
- For instance, the linked list can be defined as a data structure consisting of an object referencing a list (or null).
+ For eksempel kan en linked list defineres som en datastruktur bestående af et objekt der refererer til en liste (eller null).
```js
list = { value, next -> list }
```
- Trees like HTML elements tree or the department tree from this chapter are also naturally recursive: they have branches and every branch can have other branches.
+ Træer (hierarkier) som HTML element-træer eller træer der viser afdelinger i en virksomhed er også rekursivt definerede. De har grene og hver gren kan have andre grene.
- Recursive functions can be used to walk them as we've seen in the `sumSalary` example.
+ Rekursive funktioner kan bruges til at gennemløbe dem, som vi har set i eksemplet med `sumSalary`.
-Any recursive function can be rewritten into an iterative one. And that's sometimes required to optimize stuff. But for many tasks a recursive solution is fast enough and easier to write and support.
+Enhver rekursiv funktion kan omskrives til en iterativ funktion. Og det er nogle gange nødvendigt for at optimere ydeevnen. Men for mange opgaver er en rekursiv løsning hurtig nok og nemmere at skrive og vedligeholde.
diff --git a/1-js/06-advanced-functions/01-recursion/linked-list-0.svg b/1-js/06-advanced-functions/01-recursion/linked-list-0.svg
index 5d23c7a4c..666f452ca 100644
--- a/1-js/06-advanced-functions/01-recursion/linked-list-0.svg
+++ b/1-js/06-advanced-functions/01-recursion/linked-list-0.svg
@@ -1 +1,103 @@
-
\ No newline at end of file
+
+
\ No newline at end of file
diff --git a/1-js/06-advanced-functions/01-recursion/linked-list-remove-1.svg b/1-js/06-advanced-functions/01-recursion/linked-list-remove-1.svg
index 2f37449c4..c5be2c87f 100644
--- a/1-js/06-advanced-functions/01-recursion/linked-list-remove-1.svg
+++ b/1-js/06-advanced-functions/01-recursion/linked-list-remove-1.svg
@@ -1 +1,100 @@
-
\ No newline at end of file
+
+
\ No newline at end of file
diff --git a/1-js/06-advanced-functions/01-recursion/linked-list-split.svg b/1-js/06-advanced-functions/01-recursion/linked-list-split.svg
index 6c3072130..56d7b43b0 100644
--- a/1-js/06-advanced-functions/01-recursion/linked-list-split.svg
+++ b/1-js/06-advanced-functions/01-recursion/linked-list-split.svg
@@ -1 +1,91 @@
-
\ No newline at end of file
+
+
\ No newline at end of file
diff --git a/1-js/06-advanced-functions/01-recursion/linked-list.svg b/1-js/06-advanced-functions/01-recursion/linked-list.svg
index c02744f39..948738bea 100644
--- a/1-js/06-advanced-functions/01-recursion/linked-list.svg
+++ b/1-js/06-advanced-functions/01-recursion/linked-list.svg
@@ -1 +1,85 @@
-
\ No newline at end of file
+
+
\ No newline at end of file
diff --git a/1-js/06-advanced-functions/01-recursion/recursion-pow.svg b/1-js/06-advanced-functions/01-recursion/recursion-pow.svg
index 2b970a04a..37658f3c4 100644
--- a/1-js/06-advanced-functions/01-recursion/recursion-pow.svg
+++ b/1-js/06-advanced-functions/01-recursion/recursion-pow.svg
@@ -1 +1,97 @@
-
\ No newline at end of file
+
+
\ No newline at end of file