mirror of
https://github.com/freeCodeCamp/freeCodeCamp.git
synced 2026-03-25 23:02:05 -04:00
chore(i18n,learn): processed translations (#47330)
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
---
|
||||
id: 587d7da9367417b2b2512b67
|
||||
title: Füge Elemente dem Ende eines Arrays mit Concat statt Push hinzu
|
||||
challengeType: 1
|
||||
forumTopicId: 301226
|
||||
dashedName: add-elements-to-the-end-of-an-array-using-concat-instead-of-push
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Bei funktionalem Programmieren geht es um das Erstellen und Benutzen von nicht mutierenden Funktionen.
|
||||
|
||||
In der letzten Aufgabe wurde die `concat`-Methode vorgestellt, mit der man Arrays miteinander kombinieren kann, ohne die ursprünglichen Arrays zu verändern. Vergleiche die `concat`- mit der `push`-Methode. `push` fügt ein Element am Ende desselben Arrays hinzu, für das es aufgerufen wird, was das Array verändert. Hier ist ein Beispiel:
|
||||
|
||||
```js
|
||||
const arr = [1, 2, 3];
|
||||
arr.push([4, 5, 6]);
|
||||
```
|
||||
|
||||
`arr` hätte nun den modifizierten Wert `[1, 2, 3, [4, 5, 6]]`, was nicht dem praktischen Programmierweg entspricht.
|
||||
|
||||
`concat` bietet eine Möglichkeit, neue Elemente an das Ende eines Arrays anzuhängen, ohne dass es zu veränderlichen Auswirkungen kommt.
|
||||
|
||||
# --instructions--
|
||||
|
||||
Ändere die `nonMutatingPush`-Funktion so, dass sie `concat` anstelle von `push` verwendet, um `newItem` dem Ende von `original` hinzuzufügen. Die Funktion sollte ein Array zurückgeben.
|
||||
|
||||
# --hints--
|
||||
|
||||
Dein Code sollte die `concat` Methode verwenden.
|
||||
|
||||
```js
|
||||
assert(code.match(/\.concat/g));
|
||||
```
|
||||
|
||||
Dein Code sollte nicht die `push` Methode verwenden.
|
||||
|
||||
```js
|
||||
assert(!code.match(/\.?[\s\S]*?push/g));
|
||||
```
|
||||
|
||||
Das `first` Array sollte sich nicht ändern.
|
||||
|
||||
```js
|
||||
assert(JSON.stringify(first) === JSON.stringify([1, 2, 3]));
|
||||
```
|
||||
|
||||
Das `second` Array sollte sich nicht ändern.
|
||||
|
||||
```js
|
||||
assert(JSON.stringify(second) === JSON.stringify([4, 5]));
|
||||
```
|
||||
|
||||
`nonMutatingPush([1, 2, 3], [4, 5])` sollte `[1, 2, 3, 4, 5]` zurückgeben.
|
||||
|
||||
```js
|
||||
assert(
|
||||
JSON.stringify(nonMutatingPush([1, 2, 3], [4, 5])) ===
|
||||
JSON.stringify([1, 2, 3, 4, 5])
|
||||
);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function nonMutatingPush(original, newItem) {
|
||||
// Only change code below this line
|
||||
return original.push(newItem);
|
||||
|
||||
// Only change code above this line
|
||||
}
|
||||
|
||||
const first = [1, 2, 3];
|
||||
const second = [4, 5];
|
||||
nonMutatingPush(first, second);
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function nonMutatingPush(original, newItem) {
|
||||
return original.concat(newItem);
|
||||
}
|
||||
const first = [1, 2, 3];
|
||||
const second = [4, 5];
|
||||
```
|
||||
@@ -0,0 +1,84 @@
|
||||
---
|
||||
id: 587d7dab367417b2b2512b6d
|
||||
title: Verwende funktionale Programmierung, um Strings in URL-Slugs umzuwandeln
|
||||
challengeType: 1
|
||||
forumTopicId: 301227
|
||||
dashedName: apply-functional-programming-to-convert-strings-to-url-slugs
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Die letzten verschiedenen Herausforderungen haben eine Reihe nützlicher Array- und String-Methoden vorgestellt, die funktionalen Programmiergrundsätzen folgen. Wir haben auch über `reduce` gelernt, eine leistungsstarke Methode, um Probleme auf einfachere Formen zu reduzieren. Von der Berechnung von Durchschnittswerten bis zur Sortierung kann jede Array-Operation damit durchgeführt werden. Denke daran, dass `map` und `filter` Sonderfälle von `reduce` sind.
|
||||
|
||||
Lass uns zusammenfassen, was wir gelernt haben, um ein praktisches Problem zu lösen.
|
||||
|
||||
Bei vielen Content-Management-Sites (CMS) wird der Titel eines Beitrags zu einem Teil der URL hinzugefügt, um ein einfaches Bookmarking zu ermöglichen. Wenn du zum Beispiel einen Medium-Beitrag mit dem Titel `Stop Using Reduce` schreibst, ist es wahrscheinlich, dass die URL eine gewisse Form des Titel-Strings enthält (`.../stop-using-reduce`). Du hast das vielleicht schon auf der FreeCodeCamp-Seite bemerkt.
|
||||
|
||||
# --instructions--
|
||||
|
||||
Fülle die Funktion `urlSlug` so aus, dass sie einen String `title` umwandelt und die Version mit Bindestrich für die URL zurückgibt. Du kannst jede der Methoden verwenden, die in diesem Abschnitt behandelt werden und musst nicht `replace` verwenden. Hier sind die Anforderungen:
|
||||
|
||||
Die Eingabe ist ein String mit Leerzeichen und Wörtern in Großbuchstaben
|
||||
|
||||
Die Ausgabe ist ein String, bei der die Leerzeichen zwischen den Wörtern durch einen Bindestrich (`-`) ersetzt werden.
|
||||
|
||||
Die Ausgabe sollte nur Kleinbuchstaben enthalten
|
||||
|
||||
Die Ausgabe sollte keine Leerzeichen haben
|
||||
|
||||
# --hints--
|
||||
|
||||
Dein Code sollte nicht die `replace` Methode für diese Challenge verwenden.
|
||||
|
||||
```js
|
||||
assert(!code.match(/\.?[\s\S]*?replace/g));
|
||||
```
|
||||
|
||||
`urlSlug("Winter Is Coming")` sollte den String `winter-is-coming` zurückgeben.
|
||||
|
||||
```js
|
||||
assert(urlSlug('Winter Is Coming') === 'winter-is-coming');
|
||||
```
|
||||
|
||||
`urlSlug(" Winter Is Coming")` sollte den String `winter-is-coming` zurückgeben.
|
||||
|
||||
```js
|
||||
assert(urlSlug(' Winter Is Coming') === 'winter-is-coming');
|
||||
```
|
||||
|
||||
`urlSlug("A Mind Needs Books Like A Sword Needs A Whetstone")` sollte den String `a-mind-needs-books-like-a-sword-needs-a-whetstone` zurückgeben.
|
||||
|
||||
```js
|
||||
assert(
|
||||
urlSlug('A Mind Needs Books Like A Sword Needs A Whetstone') ===
|
||||
'a-mind-needs-books-like-a-sword-needs-a-whetstone'
|
||||
);
|
||||
```
|
||||
|
||||
`urlSlug("Hold The Door")` sollte den String `hold-the-door` zurückgeben.
|
||||
|
||||
```js
|
||||
assert(urlSlug('Hold The Door') === 'hold-the-door');
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
// Only change code below this line
|
||||
function urlSlug(title) {
|
||||
|
||||
|
||||
}
|
||||
// Only change code above this line
|
||||
urlSlug("A Mind Needs Books Like A Sword Needs A Whetstone");
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function urlSlug(title) {
|
||||
return title.trim().split(/\s+/).join("-").toLowerCase();
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,78 @@
|
||||
---
|
||||
id: 587d7b8e367417b2b2512b5e
|
||||
title: Vermeide Veränderungen und Nebeneffekte durch die Verwendung von funktionaler Programmierung
|
||||
challengeType: 1
|
||||
forumTopicId: 301228
|
||||
dashedName: avoid-mutations-and-side-effects-using-functional-programming
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Falls du es noch nicht herausgefunden hast: Das Problem in der letzten Aufgabe lag beim `splice`-Aufruf in der `tabClose()`-Funktion. Leider ändert `splice` das ursprüngliche Array, auf dem es aufgerufen wird so, dass der zweite Aufruf dazu ein modifiziertes Array verwendet und unerwartete Ergebnisse lieferte.
|
||||
|
||||
Dies ist ein kleines Beispiel für ein viel größeres Muster - du rufst eine Funktion für eine Variable, ein Array oder ein Objekt auf und die Funktion ändert die Variable oder etwas im Objekt.
|
||||
|
||||
Eines der Kernprinzipien der funktionalen Programmierung ist, die Dinge nicht zu ändern. Änderungen führen zu Bugs. Es ist einfacher, Fehler zu vermeiden, wenn du weißt, dass deine Funktionen nichts verändern, einschließlich der Funktionsargumente oder einer globalen Variable.
|
||||
|
||||
Das vorherige Beispiel hatte keine komplizierten Aktionen, aber die `splice` Methode veränderte das ursprüngliche Array und führte zu einem Fehler.
|
||||
|
||||
Denk daran, dass in der funktionalen Programmierung das Ändern oder Verändern von Dingen <dfn>Mutation</dfn> genannt wird und das Ergebnis wird <dfn>Nebenwirkung</dfn> genannt. Eine Funktion sollte idealerweise eine <dfn>pure function</dfn> sein, das heißt, sie verursacht keine Nebenwirkungen.
|
||||
|
||||
Lass uns versuchen, diese Disziplin zu meistern und keine Variablen oder Objekte in unserem Code zu verändern.
|
||||
|
||||
# --instructions--
|
||||
|
||||
Fülle den Code für die Funktion `incrementer` so aus, dass sie den Wert der globalen Variablen `fixedValue` plus eins zurückgibt.
|
||||
|
||||
# --hints--
|
||||
|
||||
Deine Funktion `incrementer` sollte den Wert von `fixedValue` (d.h. `4`) nicht ändern.
|
||||
|
||||
```js
|
||||
incrementer();
|
||||
assert(fixedValue === 4);
|
||||
```
|
||||
|
||||
Deine `incrementer` Funktion sollte einen Wert zurückgeben, der größer ist als der Wert von `fixedValue`.
|
||||
|
||||
```js
|
||||
const __newValue = incrementer();
|
||||
assert(__newValue === 5);
|
||||
```
|
||||
|
||||
Deine `incrementer` Funktion sollte einen Wert basierend auf dem globalen `fixedValue` Variablenwert zurückgeben.
|
||||
|
||||
```js
|
||||
(function () {
|
||||
fixedValue = 10;
|
||||
const newValue = incrementer();
|
||||
assert(fixedValue === 10 && newValue === 11);
|
||||
fixedValue = 4;
|
||||
})();
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
// The global variable
|
||||
let fixedValue = 4;
|
||||
|
||||
function incrementer() {
|
||||
// Only change code below this line
|
||||
|
||||
|
||||
// Only change code above this line
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
let fixedValue = 4
|
||||
|
||||
function incrementer() {
|
||||
return fixedValue + 1
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,89 @@
|
||||
---
|
||||
id: 587d7daa367417b2b2512b6c
|
||||
title: Ein Array mit der join-Methode zu einem String kombinieren
|
||||
challengeType: 1
|
||||
forumTopicId: 18221
|
||||
dashedName: combine-an-array-into-a-string-using-the-join-method
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Die Methode `join` wird verwendet, um die Elemente eines Arrays miteinander zu verbinden und einen String zu erstellen. Es wird ein Argument für das Trennzeichen benötigt, das verwendet wird, um die Array-Elemente im String zu trennen.
|
||||
|
||||
Hier ist ein Beispiel:
|
||||
|
||||
```js
|
||||
const arr = ["Hello", "World"];
|
||||
const str = arr.join(" ");
|
||||
```
|
||||
|
||||
`str` sollte einen Wert des Strings `Hello World` haben.
|
||||
# --instructions--
|
||||
|
||||
Benutze (unter anderem) die `join` Methode innerhalb der `sentensify` Funktion, um aus den Wörtern im String `str` einen Satz zu bilden. Die Funktion sollte einen String zurückgeben. Zum Beispiel würde `I-like-Star-Wars` in `I like Star Wars` konvertiert werden. Verwende bei dieser Herausforderung nicht die `replace` Methode.
|
||||
|
||||
# --hints--
|
||||
|
||||
Dein Code sollte die `join` Methode verwenden.
|
||||
|
||||
```js
|
||||
assert(code.match(/\.join/g));
|
||||
```
|
||||
|
||||
Dein Code sollte nicht die `replace` Methode verwenden.
|
||||
|
||||
```js
|
||||
assert(!code.match(/\.?[\s\S]*?replace/g));
|
||||
```
|
||||
|
||||
`sentensify("May-the-force-be-with-you")` sollte einen String zurückgeben.
|
||||
|
||||
```js
|
||||
assert(typeof sentensify('May-the-force-be-with-you') === 'string');
|
||||
```
|
||||
|
||||
`sentensify("May-the-force-be-with-you")` sollte den String `May the force be with you` zurückgeben.
|
||||
|
||||
```js
|
||||
assert(sentensify('May-the-force-be-with-you') === 'May the force be with you');
|
||||
```
|
||||
|
||||
`sentensify("The.force.is.strong.with.this.one")` sollte den String `The force is strong with this one` zurückgeben.
|
||||
|
||||
```js
|
||||
assert(
|
||||
sentensify('The.force.is.strong.with.this.one') ===
|
||||
'The force is strong with this one'
|
||||
);
|
||||
```
|
||||
|
||||
`sentensify("There,has,been,an,awakening")` sollte den String `There has been an awakening` zurückgegeben.
|
||||
|
||||
```js
|
||||
assert(
|
||||
sentensify('There,has,been,an,awakening') === 'There has been an awakening'
|
||||
);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function sentensify(str) {
|
||||
// Only change code below this line
|
||||
|
||||
|
||||
// Only change code above this line
|
||||
}
|
||||
|
||||
sentensify("May-the-force-be-with-you");
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function sentensify(str) {
|
||||
return str.split(/\W/).join(' ');
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,77 @@
|
||||
---
|
||||
id: 587d7da9367417b2b2512b66
|
||||
title: Kombiniere zwei Arrays mit der concat-Methode
|
||||
challengeType: 1
|
||||
forumTopicId: 301229
|
||||
dashedName: combine-two-arrays-using-the-concat-method
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
<dfn>Concatenation</dfn> bedeutet, dass man Elemente miteinander verbindet. JavaScript bietet die `concat` Methode für Strings und Arrays, die auf die gleiche Weise funktionieren. Bei Arrays wird diese Methode mit einem aufgerufen, dann wird ein weiteres Array als Argument an `concat` übergeben, das an das Ende des ersten Arrays angehängt wird. Sie gibt ein neues Array zurück und verändert keines der ursprünglichen Arrays. Hier ist ein Beispiel:
|
||||
|
||||
```js
|
||||
[1, 2, 3].concat([4, 5, 6]);
|
||||
```
|
||||
|
||||
Das zurückgegebene Array wäre `[1, 2, 3, 4, 5, 6]`.
|
||||
|
||||
# --instructions--
|
||||
|
||||
Verwende die `concat` Methode in der `nonMutatingConcat` Funktion, um `attach` an das Ende von `original` zu verknüpfen. Die Funktion sollte das verkettete Array zurückgeben.
|
||||
|
||||
# --hints--
|
||||
|
||||
Dein Code sollte die `concat` Methode verwenden.
|
||||
|
||||
```js
|
||||
assert(code.match(/\.concat/g));
|
||||
```
|
||||
|
||||
Das `first` Array sollte sich nicht ändern.
|
||||
|
||||
```js
|
||||
assert(JSON.stringify(first) === JSON.stringify([1, 2, 3]));
|
||||
```
|
||||
|
||||
Das `second` Array sollte sich nicht ändern.
|
||||
|
||||
```js
|
||||
assert(JSON.stringify(second) === JSON.stringify([4, 5]));
|
||||
```
|
||||
|
||||
`nonMutatingConcat([1, 2, 3], [4, 5])` sollte `[1, 2, 3, 4, 5]` zurückgeben.
|
||||
|
||||
```js
|
||||
assert(
|
||||
JSON.stringify(nonMutatingConcat([1, 2, 3], [4, 5])) ===
|
||||
JSON.stringify([1, 2, 3, 4, 5])
|
||||
);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function nonMutatingConcat(original, attach) {
|
||||
// Only change code below this line
|
||||
|
||||
|
||||
// Only change code above this line
|
||||
}
|
||||
|
||||
const first = [1, 2, 3];
|
||||
const second = [4, 5];
|
||||
nonMutatingConcat(first, second);
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function nonMutatingConcat(original, attach) {
|
||||
return original.concat(attach);
|
||||
}
|
||||
const first = [1, 2, 3];
|
||||
const second = [4, 5];
|
||||
```
|
||||
@@ -0,0 +1,72 @@
|
||||
---
|
||||
id: 587d7b8f367417b2b2512b62
|
||||
title: Eine map auf einem Prototypen implementieren
|
||||
challengeType: 1
|
||||
forumTopicId: 301230
|
||||
dashedName: implement-map-on-a-prototype
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Wie du bei der Anwendung von `Array.prototype.map()` oder kurz `map()` gesehen hast, gibt die Methode `map` ein Array mit der gleichen Länge zurück wie das Array, mit dem es aufgerufen wurde. Außerdem verändert sie das ursprüngliche Array nicht, solange es die Callback-Funktion nicht tut.
|
||||
|
||||
Anders ausgedrückt: `map` ist eine reine Funktion und ihre Ausgabe hängt ausschließlich von ihren Eingaben ab. Außerdem nimmt es eine andere Funktion als Argument.
|
||||
|
||||
Du kannst viel über die `map`-Methode lernen, wenn du deine eigene Version implementierst. Es wird empfohlen, eine `for` Schleife oder `Array.prototype.forEach()` zu verwenden.
|
||||
|
||||
# --instructions--
|
||||
|
||||
Schreibe dein eigenes `Array.prototype.myMap()`, welches sich genau wie `Array.prototype.map()` verhält. Du solltest nicht die eingebaute `map` Methode verwenden. Die `Array` Instanz kann in der `myMap` Methode mit `this` aufgerufen werden.
|
||||
|
||||
# --hints--
|
||||
|
||||
`new_s` sollte `[46, 130, 196, 10]` entsprechen.
|
||||
|
||||
```js
|
||||
assert(JSON.stringify(new_s) === JSON.stringify([46, 130, 196, 10]));
|
||||
```
|
||||
|
||||
Dein Code sollte nicht die `map` Methode verwenden.
|
||||
|
||||
```js
|
||||
assert(!code.match(/\.?[\s\S]*?map/g));
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
// The global variable
|
||||
const s = [23, 65, 98, 5];
|
||||
|
||||
Array.prototype.myMap = function(callback) {
|
||||
const newArray = [];
|
||||
// Only change code below this line
|
||||
|
||||
// Only change code above this line
|
||||
return newArray;
|
||||
};
|
||||
|
||||
const new_s = s.myMap(function(item) {
|
||||
return item * 2;
|
||||
});
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
const s = [23, 65, 98, 5];
|
||||
|
||||
Array.prototype.myMap = function(callback) {
|
||||
const newArray = [];
|
||||
for (const elem of this) {
|
||||
newArray.push(callback(elem));
|
||||
}
|
||||
return newArray;
|
||||
};
|
||||
|
||||
const new_s = s.myMap(function(item) {
|
||||
return item * 2;
|
||||
});
|
||||
```
|
||||
@@ -0,0 +1,67 @@
|
||||
---
|
||||
id: 587d7b8f367417b2b2512b64
|
||||
title: Implementierung der Filter-Methode auf einen Prototypen
|
||||
challengeType: 1
|
||||
forumTopicId: 301231
|
||||
dashedName: implement-the-filter-method-on-a-prototype
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Du kannst viel über die `filter`-Methode lernen, wenn du deine eigene Version implementierst. Es wird empfohlen, eine `for`-Schleife oder `Array.prototype.forEach()` zu verwenden.
|
||||
|
||||
# --instructions--
|
||||
|
||||
Schreibe deinen eigenen `Array.prototype.myFilter()`, der sich genau wie `Array.prototype.filter()` verhält. Du solltest die eingebaute `filter`-Methode nicht verwenden. Die `Array`-Instanz kann in der `myFilter`-Methode mit `this` aufgerufen werden.
|
||||
|
||||
# --hints--
|
||||
|
||||
`new_s` sollte `[23, 65, 5, ]` entsprechen.
|
||||
|
||||
```js
|
||||
assert(JSON.stringify(new_s) === JSON.stringify([23, 65, 5]));
|
||||
```
|
||||
|
||||
Dein Code sollte nicht die `filter` Methode verwenden.
|
||||
|
||||
```js
|
||||
assert(!code.match(/\.?[\s\S]*?filter/g));
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
// The global variable
|
||||
const s = [23, 65, 98, 5];
|
||||
|
||||
Array.prototype.myFilter = function(callback) {
|
||||
// Only change code below this line
|
||||
const newArray = [];
|
||||
// Only change code above this line
|
||||
return newArray;
|
||||
};
|
||||
|
||||
const new_s = s.myFilter(function(item) {
|
||||
return item % 2 === 1;
|
||||
});
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
const s = [23, 65, 98, 5];
|
||||
|
||||
Array.prototype.myFilter = function(callback) {
|
||||
const newArray = [];
|
||||
for (let i = 0; i < this.length; i++) {
|
||||
if (callback(this[i])) newArray.push(this[i]);
|
||||
}
|
||||
return newArray;
|
||||
};
|
||||
|
||||
const new_s = s.myFilter(function(item) {
|
||||
return item % 2 === 1;
|
||||
});
|
||||
```
|
||||
@@ -0,0 +1,102 @@
|
||||
---
|
||||
id: 587d7dab367417b2b2512b70
|
||||
title: Einführung in Currying und partielle Anwendung
|
||||
challengeType: 1
|
||||
forumTopicId: 301232
|
||||
dashedName: introduction-to-currying-and-partial-application
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Die Anzahl der Argumente, die eine Funktion benötigt, nennt man die <dfn>Natur</dfn> der Funktion. Das <dfn>Currying</dfn> einer Funktion bedeutet, dass eine Funktion der Ordnung N in N Funktionen der Ordnung 1 transformiert wird.
|
||||
|
||||
Mit anderen Worten: Eine Funktion wird so umstrukturiert, dass sie ein Argument annimmt und dann eine andere Funktion zurückgibt, die das nächste Argument annimmt, und so weiter.
|
||||
|
||||
Hier ist ein Beispiel:
|
||||
|
||||
```js
|
||||
function unCurried(x, y) {
|
||||
return x + y;
|
||||
}
|
||||
|
||||
function curried(x) {
|
||||
return function(y) {
|
||||
return x + y;
|
||||
}
|
||||
}
|
||||
|
||||
const curried = x => y => x + y
|
||||
|
||||
curried(1)(2)
|
||||
```
|
||||
|
||||
`curried(1)(2)` würde `3` zurückgeben.
|
||||
|
||||
Das ist in deinem Programm nützlich, wenn du nicht alle Argumente für eine Funktion auf einmal angeben kannst. Du kannst jeden Funktionsaufruf in einer Variablen speichern, die die zurückgegebene Funktionsreferenz enthält, die das nächste Argument übernimmt, wenn es verfügbar ist. Hier ist ein Beispiel, in dem die Curried-Funktion aus dem obigen Beispiel verwendet wird:
|
||||
|
||||
```js
|
||||
const funcForY = curried(1);
|
||||
console.log(funcForY(2)); // 3
|
||||
```
|
||||
|
||||
In ähnlicher Weise kann <dfn>partielle Anwendung</dfn> als Anwendung einiger Argumente auf eine Funktion und die Rückgabe einer anderen Funktion, die auf weitere Argumente angewendet wird, beschrieben werden. Hier ist ein Beispiel:
|
||||
|
||||
```js
|
||||
function impartial(x, y, z) {
|
||||
return x + y + z;
|
||||
}
|
||||
|
||||
const partialFn = impartial.bind(this, 1, 2);
|
||||
partialFn(10); // 13
|
||||
```
|
||||
|
||||
# --instructions--
|
||||
|
||||
Fülle den Körper der Funktion `add` so aus, dass sie Currying verwendet, um die Parameter `x`, `y` und `z` hinzuzufügen.
|
||||
|
||||
# --hints--
|
||||
|
||||
`add(10)(20)(30)` sollte `60` zurückgeben.
|
||||
|
||||
```js
|
||||
assert(add(10)(20)(30) === 60);
|
||||
```
|
||||
|
||||
`add(1)(2)(3)` sollte `6` zurückgeben.
|
||||
|
||||
```js
|
||||
assert(add(1)(2)(3) === 6);
|
||||
```
|
||||
|
||||
`add(11)(22)(33)` sollte `66` zurückgeben.
|
||||
|
||||
```js
|
||||
assert(add(11)(22)(33) === 66);
|
||||
```
|
||||
|
||||
Dein Code sollte eine abschließende Anweisung enthalten, die `x + y + z` zurückgibt.
|
||||
|
||||
```js
|
||||
assert(code.match(/[xyz]\s*?\+\s*?[xyz]\s*?\+\s*?[xyz]/g));
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function add(x) {
|
||||
// Only change code below this line
|
||||
|
||||
|
||||
// Only change code above this line
|
||||
}
|
||||
|
||||
add(10)(20)(30);
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
const add = x => y => z => x + y + z
|
||||
```
|
||||
@@ -0,0 +1,86 @@
|
||||
---
|
||||
id: 587d7b8d367417b2b2512b5b
|
||||
title: Lerne mehr über funktionale Programmierung
|
||||
challengeType: 1
|
||||
forumTopicId: 301233
|
||||
dashedName: learn-about-functional-programming
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Funktionale Programmierung ist ein Programmierstil, bei dem die Lösungen einfache, isolierte Funktionen sind, ohne jegliche Nebeneffekte außerhalb des Funktionsumfangs: Eingabe -> Prozess ->Ausgabe ( `INPUT -> PROCESS -> OUTPUT`)
|
||||
|
||||
Bei der funktionalen Programmierung geht es um:
|
||||
|
||||
1) Isolierte Funktionen - es gibt keine Abhängigkeit vom Status des Programms, das globale Variablen enthält, die geändert werden können
|
||||
|
||||
2) Reine Funktionen - die gleiche Eingabe gibt immer die gleiche Ausgabe
|
||||
|
||||
3) Funktionen mit begrenzten Nebeneffekten - alle Änderungen oder Mutationen des Programmzustands außerhalb der Funktion werden sorgfältig kontrolliert
|
||||
|
||||
# --instructions--
|
||||
|
||||
Die Mitglieder von FreeCodeCamp lieben Tee.
|
||||
|
||||
Im Code-Editor sind die Funktionen `prepareTea` und `getTea` bereits für dich definiert. Rufe die `getTea` Funktion auf, um 40 Tassen Tee für das Team zu erhalten, und speichere sie in der `tea4TeamFCC` Variable.
|
||||
|
||||
# --hints--
|
||||
|
||||
Die Variable `tea4TeamFCC` sollte 40 Tassen Tee für das Team enthalten.
|
||||
|
||||
```js
|
||||
assert(tea4TeamFCC.length === 40);
|
||||
```
|
||||
|
||||
Die Variable `tea4TeamFCC` sollte Tassen mit grünem Tee enthalten.
|
||||
|
||||
```js
|
||||
assert(tea4TeamFCC[0] === 'greenTea');
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
// Function that returns a string representing a cup of green tea
|
||||
const prepareTea = () => 'greenTea';
|
||||
|
||||
/*
|
||||
Given a function (representing the tea type) and number of cups needed, the
|
||||
following function returns an array of strings (each representing a cup of
|
||||
a specific type of tea).
|
||||
*/
|
||||
const getTea = (numOfCups) => {
|
||||
const teaCups = [];
|
||||
|
||||
for(let cups = 1; cups <= numOfCups; cups += 1) {
|
||||
const teaCup = prepareTea();
|
||||
teaCups.push(teaCup);
|
||||
}
|
||||
return teaCups;
|
||||
};
|
||||
|
||||
// Only change code below this line
|
||||
const tea4TeamFCC = null;
|
||||
// Only change code above this line
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
const prepareTea = () => 'greenTea';
|
||||
|
||||
const getTea = (numOfCups) => {
|
||||
const teaCups = [];
|
||||
|
||||
for(let cups = 1; cups <= numOfCups; cups += 1) {
|
||||
const teaCup = prepareTea();
|
||||
teaCups.push(teaCup);
|
||||
}
|
||||
|
||||
return teaCups;
|
||||
};
|
||||
|
||||
const tea4TeamFCC = getTea(40);
|
||||
```
|
||||
@@ -0,0 +1,74 @@
|
||||
---
|
||||
id: 587d7b8e367417b2b2512b5f
|
||||
title: Übergabe von Argumenten zur Vermeidung externer Abhängigkeiten in einer Funktion
|
||||
challengeType: 1
|
||||
forumTopicId: 301234
|
||||
dashedName: pass-arguments-to-avoid-external-dependence-in-a-function
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Die letzte Aufgabe hat uns den Prinzipien der funktionalen Programmierung einen Schritt näher gebracht, aber es fehlt noch etwas.
|
||||
|
||||
Wir haben den Wert der globalen Variable nicht verändert, aber die Funktion `incrementer` würde nicht funktionieren, wenn die globale Variable `fixedValue` nicht vorhanden wäre.
|
||||
|
||||
Ein weiterer Grundsatz der funktionalen Programmierung ist, dass du deine Abhängigkeiten immer explizit deklarierst. Das heißt, wenn eine Funktion vom Vorhandensein einer Variablen oder eines Objekts abhängt, übergibst du diese Variable oder dieses Objekt direkt als Argument an die Funktion.
|
||||
|
||||
Aus diesem Prinzip ergeben sich mehrere gute Konsequenzen. Die Funktion ist einfacher zu testen, du weißt genau, welche Eingaben sie benötigt und sie hängt nicht von anderen Teilen deines Programms ab.
|
||||
|
||||
Das kann dir mehr Sicherheit geben, wenn du den Code änderst, entfernst oder neu hinzufügst. Du würdest wissen, was du ändern kannst und was nicht, und du könntest sehen, wo die möglichen Fallstricke sind.
|
||||
|
||||
Schließlich würde die Funktion immer die gleiche Ausgabe für die gleiche Menge an Eingaben produzieren, egal welcher Teil des Codes sie ausführt.
|
||||
|
||||
# --instructions--
|
||||
|
||||
Aktualisieren wir die Funktion `incrementer`, um ihre Abhängigkeiten klar zu deklarieren.
|
||||
|
||||
Schreibe die Funktion `incrementer` so, dass sie ein Argument annimmt und dann ein Ergebnis zurückgibt, nachdem sie den Wert um eins erhöht hat.
|
||||
|
||||
# --hints--
|
||||
|
||||
Deine Funktion `incrementer` sollte den Wert von `fixedValue` (der `4` ist) nicht verändern.
|
||||
|
||||
```js
|
||||
assert(fixedValue === 4);
|
||||
```
|
||||
|
||||
Deine Funktion `incrementer` sollte ein Argument benötigen.
|
||||
|
||||
```js
|
||||
assert(incrementer.length === 1);
|
||||
```
|
||||
|
||||
Deine Funktion `incrementer` sollte einen Wert zurückgeben, der um eins größer ist als der Wert von `fixedValue`.
|
||||
|
||||
```js
|
||||
const __newValue = incrementer(fixedValue);
|
||||
assert(__newValue === 5);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
// The global variable
|
||||
let fixedValue = 4;
|
||||
|
||||
// Only change code below this line
|
||||
function incrementer() {
|
||||
|
||||
|
||||
// Only change code above this line
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
let fixedValue = 4;
|
||||
|
||||
function incrementer(fixedValue) {
|
||||
return fixedValue + 1;
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,133 @@
|
||||
---
|
||||
id: 587d7b8f367417b2b2512b60
|
||||
title: Refaktoriere globale Variablen außerhalb von Funktionen
|
||||
challengeType: 1
|
||||
forumTopicId: 301235
|
||||
dashedName: refactor-global-variables-out-of-functions
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Bisher haben wir zwei unterschiedliche Prinzipien der funktionalen Programmierung kennengelernt:
|
||||
|
||||
1) Verändere keine Variablen oder Objekte - erstelle neue Variablen und Objekte und gib sie bei Bedarf aus einer Funktion zurück. Tipp: Wenn du etwas wie `const newArr = arrVar` verwendest, wobei `arrVar` ein Array ist, wird einfach ein Verweis auf die bestehende Variable erstellt und keine Kopie. Wenn du also einen Wert in `newArr` änderst, ändert sich der Wert in `arrVar`.
|
||||
|
||||
2) Deklariere Funktionsparameter - jede Berechnung innerhalb einer Funktion hängt nur von den Argumenten ab, die der Funktion übergeben werden, und nicht von einem globalen Objekt oder einer Variablen.
|
||||
|
||||
Das Addieren von eins zu einer Zahl ist nicht sehr aufregend, aber wir können diese Prinzipien anwenden, wenn wir mit Arrays oder komplexeren Objekten arbeiten.
|
||||
|
||||
# --instructions--
|
||||
|
||||
Schreibe den Code so um, dass das globale Array `bookList` in keiner der Funktionen verändert wird. Die Funktion `add` soll den angegebenen Buchtitel `bookName` an das Ende des übergebenen Arrays anfügen und ein neues Array (Liste) zurückgeben. Die Funktion `remove` soll den angegebenen `bookName` aus dem Array entfernen, das ihr übergeben wurde.
|
||||
|
||||
**Hinweis:** Beide Funktionen sollten ein Array zurückgeben, und alle neuen Parameter sollten vor dem Parameter `bookName` hinzugefügt werden.
|
||||
|
||||
# --hints--
|
||||
|
||||
`bookList` sollte sich nicht ändern und immer noch `["The Hound of the Baskervilles", "On The Electrodynamics of Moving Bodies", "Philosophiæ Naturalis Principia Mathematica", "Disquisitiones Arithmeticae"]` entsprechen.
|
||||
|
||||
```js
|
||||
add(bookList, "Test");
|
||||
remove(bookList, "The Hound of the Baskervilles");
|
||||
assert(
|
||||
JSON.stringify(bookList) ===
|
||||
JSON.stringify([
|
||||
'The Hound of the Baskervilles',
|
||||
'On The Electrodynamics of Moving Bodies',
|
||||
'Philosophiæ Naturalis Principia Mathematica',
|
||||
'Disquisitiones Arithmeticae'
|
||||
])
|
||||
);
|
||||
```
|
||||
|
||||
`add(bookList, "A Brief History of Time")` sollte `["The Hound of the Baskervilles", "On The Electrodynamics of Moving Bodies", "Philosophiæ Naturalis Principia Mathematica", "Disquisitiones Arithmeticae", "A Brief History of Time"]` zurückgeben.
|
||||
|
||||
```js
|
||||
assert(
|
||||
JSON.stringify(add(bookList, "A Brief History of Time")) ===
|
||||
JSON.stringify([
|
||||
'The Hound of the Baskervilles',
|
||||
'On The Electrodynamics of Moving Bodies',
|
||||
'Philosophiæ Naturalis Principia Mathematica',
|
||||
'Disquisitiones Arithmeticae',
|
||||
'A Brief History of Time'
|
||||
])
|
||||
);
|
||||
```
|
||||
|
||||
`remove(bookList, "On The Electrodynamics of Moving Bodies")` sollte `["The Hound of the Baskervilles", "Philosophiæ Naturalis Principia Mathematica", "Disquisitiones Arithmeticae"]` zurückgeben.
|
||||
|
||||
```js
|
||||
assert(
|
||||
JSON.stringify(remove(bookList, 'On The Electrodynamics of Moving Bodies')) ===
|
||||
JSON.stringify([
|
||||
'The Hound of the Baskervilles',
|
||||
'Philosophiæ Naturalis Principia Mathematica',
|
||||
'Disquisitiones Arithmeticae'
|
||||
])
|
||||
);
|
||||
```
|
||||
|
||||
`remove(add(bookList, "A Brief History of Time"), "On The Electrodynamics of Moving Bodies");` sollte gleich `["The Hound of the Baskervilles", "Philosophiæ Naturalis Principia Mathematica", "Disquisitiones Arithmeticae", "A Brief History of Time"]` sein.
|
||||
|
||||
```js
|
||||
assert(
|
||||
JSON.stringify(remove(add(bookList, 'A Brief History of Time'), 'On The Electrodynamics of Moving Bodies')) ===
|
||||
JSON.stringify([
|
||||
'The Hound of the Baskervilles',
|
||||
'Philosophiæ Naturalis Principia Mathematica',
|
||||
'Disquisitiones Arithmeticae',
|
||||
'A Brief History of Time'
|
||||
])
|
||||
);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
// The global variable
|
||||
const bookList = ["The Hound of the Baskervilles", "On The Electrodynamics of Moving Bodies", "Philosophiæ Naturalis Principia Mathematica", "Disquisitiones Arithmeticae"];
|
||||
|
||||
// Change code below this line
|
||||
function add(bookName) {
|
||||
|
||||
bookList.push(bookName);
|
||||
return bookList;
|
||||
|
||||
// Change code above this line
|
||||
}
|
||||
|
||||
// Change code below this line
|
||||
function remove(bookName) {
|
||||
const book_index = bookList.indexOf(bookName);
|
||||
if (book_index >= 0) {
|
||||
|
||||
bookList.splice(book_index, 1);
|
||||
return bookList;
|
||||
|
||||
// Change code above this line
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
// The global variable
|
||||
const bookList = ["The Hound of the Baskervilles", "On The Electrodynamics of Moving Bodies", "Philosophiæ Naturalis Principia Mathematica", "Disquisitiones Arithmeticae"];
|
||||
|
||||
function add(bookList, bookName) {
|
||||
return [...bookList, bookName];
|
||||
}
|
||||
|
||||
function remove(bookList, bookName) {
|
||||
const bookListCopy = [...bookList];
|
||||
const bookNameIndex = bookList.indexOf(bookName);
|
||||
if (bookNameIndex >= 0) {
|
||||
bookListCopy.splice(bookNameIndex, 1);
|
||||
}
|
||||
return bookListCopy;
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,84 @@
|
||||
---
|
||||
id: 9d7123c8c441eeafaeb5bdef
|
||||
title: Entfernen von Elementen aus einem Array mit slice statt splice
|
||||
challengeType: 1
|
||||
forumTopicId: 301236
|
||||
dashedName: remove-elements-from-an-array-using-slice-instead-of-splice
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Ein häufiges Muster bei der Arbeit mit Arrays ist, dass du Elemente entfernen und den Rest des Arrays behalten willst. JavaScript bietet dafür die Methode `splice`, die Argumente für den Index, wo mit dem Entfernen von Elementen begonnen werden soll, und dann die Anzahl der zu entfernenden Elemente entgegennimmt. Wenn das zweite Argument nicht angegeben wird, werden standardmäßig die Einträge bis zum Ende entfernt. Allerdings verändert die Methode `splice` das ursprüngliche Array, auf das sie angewendet wird. Hier ist ein Beispiel:
|
||||
|
||||
```js
|
||||
const cities = ["Chicago", "Delhi", "Islamabad", "London", "Berlin"];
|
||||
cities.splice(3, 1);
|
||||
```
|
||||
|
||||
Hier gibt `splice` den String `London` zurück und löscht ihn aus dem Array cities. `cities` wird den Wert `["Chicago", "Delhi", "Islamabad", "Berlin"]` haben.
|
||||
|
||||
Wie wir in der letzten Aufgabe gesehen haben, verändert die Methode `slice` das ursprüngliche Array nicht, sondern gibt ein neues Array zurück, das in einer Variablen gespeichert werden kann. Du erinnerst dich, dass die Methode `slice` zwei Argumente für die Indizes für den Anfang und das Ende des Slice benötigt (das Ende ist nicht eingeschlossen) und diese Elemente in einem neuen Array zurückgibt. Wenn du die Methode `slice` anstelle von `splice` verwendest, vermeidest du alle Array-mutierenden Nebeneffekte.
|
||||
|
||||
# --instructions--
|
||||
|
||||
Schreibe die Funktion `nonMutatingSplice` um, indem du `slice` anstelle von `splice` verwendest. Sie sollte das übergebene Array `cities` auf eine Länge von 3 begrenzen und ein neues Array mit nur den ersten drei Elementen zurückgeben.
|
||||
|
||||
Verändere das ursprüngliche Array, das der Funktion übergeben wird, nicht.
|
||||
|
||||
# --hints--
|
||||
|
||||
Dein Code sollte die Methode `slice` verwenden.
|
||||
|
||||
```js
|
||||
assert(code.match(/\.slice/g));
|
||||
```
|
||||
|
||||
Dein Code sollte nicht die Methode `splice` verwenden.
|
||||
|
||||
```js
|
||||
assert(!code.match(/\.?[\s\S]*?splice/g));
|
||||
```
|
||||
|
||||
Das Array `inputCities` sollte sich nicht ändern.
|
||||
|
||||
```js
|
||||
assert(
|
||||
JSON.stringify(inputCities) ===
|
||||
JSON.stringify(['Chicago', 'Delhi', 'Islamabad', 'London', 'Berlin'])
|
||||
);
|
||||
```
|
||||
|
||||
`nonMutatingSplice(["Chicago", "Delhi", "Islamabad", "London", "Berlin"])` sollte `["Chicago", "Delhi", "Islamabad"]` zurückgeben.
|
||||
|
||||
```js
|
||||
assert(
|
||||
JSON.stringify(
|
||||
nonMutatingSplice(['Chicago', 'Delhi', 'Islamabad', 'London', 'Berlin'])
|
||||
) === JSON.stringify(['Chicago', 'Delhi', 'Islamabad'])
|
||||
);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function nonMutatingSplice(cities) {
|
||||
// Only change code below this line
|
||||
return cities.splice(3);
|
||||
|
||||
// Only change code above this line
|
||||
}
|
||||
|
||||
const inputCities = ["Chicago", "Delhi", "Islamabad", "London", "Berlin"];
|
||||
nonMutatingSplice(inputCities);
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function nonMutatingSplice(cities) {
|
||||
return cities.slice(0,3);
|
||||
}
|
||||
const inputCities = ["Chicago", "Delhi", "Islamabad", "London", "Berlin"];
|
||||
```
|
||||
@@ -0,0 +1,90 @@
|
||||
---
|
||||
id: 587d7da9367417b2b2512b6a
|
||||
title: Ein sortiertes Array zurückgeben, ohne das ursprüngliche Array zu verändern
|
||||
challengeType: 1
|
||||
forumTopicId: 301237
|
||||
dashedName: return-a-sorted-array-without-changing-the-original-array
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Ein Nebeneffekt der Methode `sort` ist, dass sie die Reihenfolge der Elemente im ursprünglichen Array ändert. Mit anderen Worten: Sie verändert das Array an Ort und Stelle. Eine Möglichkeit, dies zu vermeiden, ist, zuerst ein leeres Array mit dem zu sortierenden Array zu verketten (denk daran, dass `slice` und `concat` ein neues Array zurückgeben) und dann die Methode `sort` auszuführen.
|
||||
|
||||
# --instructions--
|
||||
|
||||
Verwende die Methode `sort` in der Funktion `nonMutatingSort`, um die Elemente eines Arrays in aufsteigender Reihenfolge zu sortieren. Die Funktion sollte ein neues Array zurückgeben und die Variable `globalArray` nicht verändern.
|
||||
|
||||
# --hints--
|
||||
|
||||
Dein Code sollte die Methode `sort` verwenden.
|
||||
|
||||
```js
|
||||
assert(nonMutatingSort.toString().match(/\.sort/g));
|
||||
```
|
||||
|
||||
Die Variable `globalArray` sollte sich nicht ändern.
|
||||
|
||||
```js
|
||||
assert(JSON.stringify(globalArray) === JSON.stringify([5, 6, 3, 2, 9]));
|
||||
```
|
||||
|
||||
`nonMutatingSort(globalArray)` sollte `[2, 3, 5, 6, 9]` zurückgeben.
|
||||
|
||||
```js
|
||||
assert(
|
||||
JSON.stringify(nonMutatingSort(globalArray)) ===
|
||||
JSON.stringify([2, 3, 5, 6, 9])
|
||||
);
|
||||
```
|
||||
|
||||
`nonMutatingSort(globalArray)` sollte nicht hart kodiert sein.
|
||||
|
||||
```js
|
||||
assert(!nonMutatingSort.toString().match(/\[.*?[23569].*?\]/gs));
|
||||
```
|
||||
|
||||
Die Funktion sollte ein neues Array zurückgeben, nicht das Array, das ihr übergeben wurde.
|
||||
|
||||
```js
|
||||
assert(nonMutatingSort(globalArray) !== globalArray);
|
||||
```
|
||||
|
||||
`nonMutatingSort([1, 30, 4, 21, 100000])` sollte `[1, 4, 21, 30, 100000]` zurückgeben.
|
||||
|
||||
```js
|
||||
assert(JSON.stringify(nonMutatingSort([1, 30, 4, 21, 100000])) ===
|
||||
JSON.stringify([1, 4, 21, 30, 100000]))
|
||||
```
|
||||
|
||||
`nonMutatingSort([140000, 104, 99])` sollte `[99, 104, 140000]` zurückgeben.
|
||||
|
||||
```js
|
||||
assert(JSON.stringify(nonMutatingSort([140000, 104, 99])) ===
|
||||
JSON.stringify([99, 104, 140000]))
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
const globalArray = [5, 6, 3, 2, 9];
|
||||
|
||||
function nonMutatingSort(arr) {
|
||||
// Only change code below this line
|
||||
|
||||
|
||||
// Only change code above this line
|
||||
}
|
||||
|
||||
nonMutatingSort(globalArray);
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
const globalArray = [5, 6, 3, 2, 9];
|
||||
function nonMutatingSort(arr) {
|
||||
return [].concat(arr).sort((a,b) => a-b);
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,93 @@
|
||||
---
|
||||
id: 587d7b90367417b2b2512b65
|
||||
title: Teil eines Arrays mit der slice-Methode zurückgeben
|
||||
challengeType: 1
|
||||
forumTopicId: 301239
|
||||
dashedName: return-part-of-an-array-using-the-slice-method
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Die Methode `slice` gibt eine Kopie bestimmter Elemente eines Arrays zurück. Sie kann zwei Argumente annehmen: Das erste gibt den Index an, an dem das Slice beginnen soll, das zweite ist der Index, an dem das Slice enden soll (und ist nicht exklusiv). Wenn die Argumente nicht angegeben werden, wird standardmäßig am Anfang des Arrays begonnen und bis zum Ende durchgezogen, was eine einfache Möglichkeit ist, eine Kopie des gesamten Arrays zu erstellen. Die Methode `slice` verändert das ursprüngliche Array nicht, sondern gibt ein neues zurück.
|
||||
|
||||
Hier ist ein Beispiel:
|
||||
|
||||
```js
|
||||
const arr = ["Cat", "Dog", "Tiger", "Zebra"];
|
||||
const newArray = arr.slice(1, 3);
|
||||
```
|
||||
|
||||
`newArray` würde den Wert `["Dog", "Tiger"]` haben.
|
||||
|
||||
# --instructions--
|
||||
|
||||
Verwende die Methode `slice` in der Funktion `sliceArray`, um einen Teil des Arrays `anim` mit den angegebenen Indizes `beginSlice` und `endSlice` zurückzugeben. Die Funktion sollte ein Array zurückgeben.
|
||||
|
||||
# --hints--
|
||||
|
||||
Dein Code sollte die Methode `slice` verwenden.
|
||||
|
||||
```js
|
||||
assert(code.match(/\.slice/g));
|
||||
```
|
||||
|
||||
Die Variable `inputAnim` sollte sich nicht ändern.
|
||||
|
||||
```js
|
||||
assert(
|
||||
JSON.stringify(inputAnim) ===
|
||||
JSON.stringify(['Cat', 'Dog', 'Tiger', 'Zebra', 'Ant'])
|
||||
);
|
||||
```
|
||||
|
||||
`sliceArray(["Cat", "Dog", "Tiger", "Zebra", "Ant"], 1, 3)` sollte `["Dog", "Tiger"]` zurückgeben.
|
||||
|
||||
```js
|
||||
assert(
|
||||
JSON.stringify(sliceArray(['Cat', 'Dog', 'Tiger', 'Zebra', 'Ant'], 1, 3)) ===
|
||||
JSON.stringify(['Dog', 'Tiger'])
|
||||
);
|
||||
```
|
||||
|
||||
`sliceArray(["Cat", "Dog", "Tiger", "Zebra", "Ant"], 0, 1)` sollte `["Cat"]` zurückgeben.
|
||||
|
||||
```js
|
||||
assert(
|
||||
JSON.stringify(sliceArray(['Cat', 'Dog', 'Tiger', 'Zebra', 'Ant'], 0, 1)) ===
|
||||
JSON.stringify(['Cat'])
|
||||
);
|
||||
```
|
||||
|
||||
`sliceArray(["Cat", "Dog", "Tiger", "Zebra", "Ant"], 1, 4)` sollte `["Dog", "Tiger", "Zebra"]` zurückgeben.
|
||||
|
||||
```js
|
||||
assert(
|
||||
JSON.stringify(sliceArray(['Cat', 'Dog', 'Tiger', 'Zebra', 'Ant'], 1, 4)) ===
|
||||
JSON.stringify(['Dog', 'Tiger', 'Zebra'])
|
||||
);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function sliceArray(anim, beginSlice, endSlice) {
|
||||
// Only change code below this line
|
||||
|
||||
|
||||
// Only change code above this line
|
||||
}
|
||||
|
||||
const inputAnim = ["Cat", "Dog", "Tiger", "Zebra", "Ant"];
|
||||
sliceArray(inputAnim, 1, 3);
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function sliceArray(anim, beginSlice, endSlice) {
|
||||
return anim.slice(beginSlice, endSlice);
|
||||
}
|
||||
const inputAnim = ["Cat", "Dog", "Tiger", "Zebra", "Ant"];
|
||||
```
|
||||
@@ -0,0 +1,101 @@
|
||||
---
|
||||
id: 587d7da9367417b2b2512b69
|
||||
title: Ein Array mit der sort-Methode alphabetisch sortieren
|
||||
challengeType: 1
|
||||
forumTopicId: 18303
|
||||
dashedName: sort-an-array-alphabetically-using-the-sort-method
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Die Methode `sort` sortiert die Elemente eines Arrays entsprechend der Callback-Funktion.
|
||||
|
||||
Zum Beispiel:
|
||||
|
||||
```js
|
||||
function ascendingOrder(arr) {
|
||||
return arr.sort(function(a, b) {
|
||||
return a - b;
|
||||
});
|
||||
}
|
||||
|
||||
ascendingOrder([1, 5, 2, 3, 4]);
|
||||
```
|
||||
|
||||
Dies würde den Wert `[1, 2, 3, 4, 5]` zurückgeben.
|
||||
|
||||
```js
|
||||
function reverseAlpha(arr) {
|
||||
return arr.sort(function(a, b) {
|
||||
return a === b ? 0 : a < b ? 1 : -1;
|
||||
});
|
||||
}
|
||||
|
||||
reverseAlpha(['l', 'h', 'z', 'b', 's']);
|
||||
```
|
||||
|
||||
Dies würde den Wert `['z', 's', 'l', 'h', 'b']` zurückgeben.
|
||||
|
||||
Die Standard-Sortiermethode von JavaScript sortiert nach dem Unicode-Punktwert eines Strings, was zu unerwarteten Ergebnissen führen kann. Daher ist es ratsam, eine Callback-Funktion bereitzustellen, die angibt, wie die Array-Elemente sortiert werden sollen. Wenn eine solche Callback-Funktion, die normalerweise `compareFunction` heißt, übergeben wird, werden die Array-Elemente nach dem Rückgabewert der `compareFunction` sortiert: Wenn `compareFunction(a,b)` für zwei Elemente `a` und `b` einen Wert kleiner als 0 zurückgibt, dann kommt `a` vor `b`. Wenn `compareFunction(a,b)` für zwei Elemente `a` und `b` einen Wert größer als 0 liefert, dann kommt `b` vor `a`. Wenn `compareFunction(a,b)` für zwei Elemente `a` und `b` einen Wert gleich 0 zurückgibt, dann bleiben `a` und `b` unverändert.
|
||||
|
||||
# --instructions--
|
||||
|
||||
Verwende die Methode `sort` in der Funktion `alphabeticalOrder`, um die Elemente von `arr` in alphabetischer Reihenfolge zu sortieren. Die Funktion sollte das sortierte Array zurückgeben.
|
||||
|
||||
# --hints--
|
||||
|
||||
Dein Code sollte die Methode `sort` verwenden.
|
||||
|
||||
```js
|
||||
assert(code.match(/\.sort/g));
|
||||
```
|
||||
|
||||
`alphabeticalOrder(["a", "d", "c", "a", "z", "g"])` sollte `["a", "a", "c", "d", "g", "z"]` zurückgeben.
|
||||
|
||||
```js
|
||||
assert(
|
||||
JSON.stringify(alphabeticalOrder(['a', 'd', 'c', 'a', 'z', 'g'])) ===
|
||||
JSON.stringify(['a', 'a', 'c', 'd', 'g', 'z'])
|
||||
);
|
||||
```
|
||||
|
||||
`alphabeticalOrder(["x", "h", "a", "m", "n", "m"])` sollte `["a", "h", "m", "m", "n", "x"]` zurückgeben.
|
||||
|
||||
```js
|
||||
assert(
|
||||
JSON.stringify(alphabeticalOrder(['x', 'h', 'a', 'm', 'n', 'm'])) ===
|
||||
JSON.stringify(['a', 'h', 'm', 'm', 'n', 'x'])
|
||||
);
|
||||
```
|
||||
|
||||
`alphabeticalOrder(["a", "a", "a", "a", "x", "t"])` sollte `["a", "a", "a", "a", "t", "x"]` zurückgeben.
|
||||
|
||||
```js
|
||||
assert(
|
||||
JSON.stringify(alphabeticalOrder(['a', 'a', 'a', 'a', 'x', 't'])) ===
|
||||
JSON.stringify(['a', 'a', 'a', 'a', 't', 'x'])
|
||||
);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function alphabeticalOrder(arr) {
|
||||
// Only change code below this line
|
||||
|
||||
return arr
|
||||
// Only change code above this line
|
||||
}
|
||||
|
||||
alphabeticalOrder(["a", "d", "c", "a", "z", "g"]);
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function alphabeticalOrder(arr) {
|
||||
return arr.sort();
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,87 @@
|
||||
---
|
||||
id: 587d7daa367417b2b2512b6b
|
||||
title: Einen String mit der split-Methode in ein Array aufteilen
|
||||
challengeType: 1
|
||||
forumTopicId: 18305
|
||||
dashedName: split-a-string-into-an-array-using-the-split-method
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Die Methode `split` zerlegt einen String in ein Array von Strings. Sie benötigt ein Argument für das Trennzeichen, das ein Zeichen zum Aufbrechen des Strings oder ein regulärer Ausdruck sein kann. Wenn das Begrenzungszeichen zum Beispiel ein Leerzeichen ist, erhältst du ein Array mit Wörtern, und wenn das Begrenzungszeichen ein leerer String ist, erhältst du ein Array mit jedem Zeichen des Strings.
|
||||
|
||||
Hier sind zwei Beispiele, die einen String mit Hilfe eines regulären Ausdrucks nach Leerzeichen und einen anderen nach Ziffern aufteilen:
|
||||
|
||||
```js
|
||||
const str = "Hello World";
|
||||
const bySpace = str.split(" ");
|
||||
|
||||
const otherString = "How9are7you2today";
|
||||
const byDigits = otherString.split(/\d/);
|
||||
```
|
||||
|
||||
`bySpace` würde den Wert `["Hello", "World"]` haben und `byDigits` würde den Wert `["How", "are", "you", "today"]` haben.
|
||||
|
||||
Da Strings unveränderlich sind, macht es die Methode `split` einfacher, mit ihnen zu arbeiten.
|
||||
|
||||
# --instructions--
|
||||
|
||||
Verwende die Methode `split` innerhalb der Funktion `splitify`, um `str` in ein Array von Wörtern zu zerlegen. Die Funktion sollte das Array zurückgeben. Beachte, dass die Wörter nicht immer durch Leerzeichen getrennt sind und das Feld keine Satzzeichen enthalten sollte.
|
||||
|
||||
# --hints--
|
||||
|
||||
Dein Code sollte die Methode `split` verwenden.
|
||||
|
||||
```js
|
||||
assert(code.match(/\.split/g));
|
||||
```
|
||||
|
||||
`splitify("Hello World,I-am code")` sollte `["Hello", "World", "I", "am", "code"]` zurückgeben.
|
||||
|
||||
```js
|
||||
assert(
|
||||
JSON.stringify(splitify('Hello World,I-am code')) ===
|
||||
JSON.stringify(['Hello', 'World', 'I', 'am', 'code'])
|
||||
);
|
||||
```
|
||||
|
||||
`splitify("Earth-is-our home")` sollte `["Earth", "is", "our", "home"]` zurückgeben.
|
||||
|
||||
```js
|
||||
assert(
|
||||
JSON.stringify(splitify('Earth-is-our home')) ===
|
||||
JSON.stringify(['Earth', 'is', 'our', 'home'])
|
||||
);
|
||||
```
|
||||
|
||||
`splitify("This.is.a-sentence")` sollte `["This", "is", "a", "sentence"]` zurückgeben.
|
||||
|
||||
```js
|
||||
assert(
|
||||
JSON.stringify(splitify('This.is.a-sentence')) ===
|
||||
JSON.stringify(['This', 'is', 'a', 'sentence'])
|
||||
);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function splitify(str) {
|
||||
// Only change code below this line
|
||||
|
||||
|
||||
// Only change code above this line
|
||||
}
|
||||
|
||||
splitify("Hello World,I-am code");
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function splitify(str) {
|
||||
return str.split(/\W/);
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,112 @@
|
||||
---
|
||||
id: 587d7b8e367417b2b2512b5c
|
||||
title: Die Terminologie der funktionalen Programmierung verstehen
|
||||
challengeType: 1
|
||||
forumTopicId: 301240
|
||||
dashedName: understand-functional-programming-terminology
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Das FCC-Team hatte einen Stimmungswandel und will jetzt zwei Sorten Tee: grünen und schwarzen Tee. Allgemeiner Fakt: Stimmungsschwankungen bei Kunden sind ziemlich normal.
|
||||
|
||||
Mit diesen Informationen müssen wir die Funktion `getTea` aus der letzten Aufgabe wieder aufgreifen, um verschiedene Teeanfragen zu bearbeiten. Wir können `getTea` so abändern, dass es eine Funktion als Parameter akzeptiert, um die Art des Tees zu ändern, den es zubereitet. Das macht `getTea` flexibler und gibt dem Programmierer mehr Kontrolle, wenn sich die Kundenanforderungen ändern.
|
||||
|
||||
Aber zuerst wollen wir ein paar funktionale Begriffe klären:
|
||||
|
||||
<dfn>Callbacks</dfn> sind die Funktionen, die in eine andere Funktion eingeschleust oder übergeben werden, um den Aufruf dieser Funktion zu bestimmen. Du hast sie vielleicht schon an andere Methoden weitergegeben, zum Beispiel in `filter`. Die Callback-Funktion teilt JavaScript die Kriterien mit, nach denen ein Array gefiltert werden soll.
|
||||
|
||||
Funktionen, die einer Variablen zugewiesen, an eine andere Funktion übergeben oder von einer anderen Funktion zurückgegeben werden können, werden <dfn>Funktionen erster Klasse</dfn> genannt. Alle Funktionen in JavaScript sind Funktionen erster Klasse.
|
||||
|
||||
Die Funktionen, die eine Funktion als Argument nehmen oder eine Funktion als Rückgabewert zurückgeben, werden <dfn>Funktionen höherer Ordnung</dfn> genannt.
|
||||
|
||||
Wenn Funktionen an eine andere Funktion übergeben oder von einer anderen Funktion zurückgegeben werden, dann können die übergebenen oder zurückgegebenen Funktionen als <dfn>Lambda</dfn> bezeichnet werden.
|
||||
|
||||
# --instructions--
|
||||
|
||||
Bereite 27 Tassen grünen Tee und 13 Tassen schwarzen Tee zu und speichere sie in den Variablen `tea4GreenTeamFCC` und `tea4BlackTeamFCC`. Beachte, dass die Funktion `getTea` geändert wurde, so dass sie jetzt eine Funktion als erstes Argument nimmt.
|
||||
|
||||
Hinweis: Die Daten (die Anzahl der Tassen Tee) werden als letztes Argument angegeben. Wir werden das in späteren Lektionen genauer besprechen.
|
||||
|
||||
# --hints--
|
||||
|
||||
Die Variable `tea4GreenTeamFCC` sollte 27 Tassen grünen Tee für das Team enthalten.
|
||||
|
||||
```js
|
||||
assert(tea4GreenTeamFCC.length === 27);
|
||||
```
|
||||
|
||||
Die Variable `tea4GreenTeamFCC` sollte Tassen mit grünem Tee enthalten.
|
||||
|
||||
```js
|
||||
assert(tea4GreenTeamFCC[0] === 'greenTea');
|
||||
```
|
||||
|
||||
Die Variable `tea4BlackTeamFCC` sollte 13 Tassen schwarzen Tee enthalten.
|
||||
|
||||
```js
|
||||
assert(tea4BlackTeamFCC.length === 13);
|
||||
```
|
||||
|
||||
Die Variable `tea4BlackTeamFCC` sollte Tassen mit schwarzem Tee enthalten.
|
||||
|
||||
```js
|
||||
assert(tea4BlackTeamFCC[0] === 'blackTea');
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
// Function that returns a string representing a cup of green tea
|
||||
const prepareGreenTea = () => 'greenTea';
|
||||
|
||||
// Function that returns a string representing a cup of black tea
|
||||
const prepareBlackTea = () => 'blackTea';
|
||||
|
||||
/*
|
||||
Given a function (representing the tea type) and number of cups needed, the
|
||||
following function returns an array of strings (each representing a cup of
|
||||
a specific type of tea).
|
||||
*/
|
||||
const getTea = (prepareTea, numOfCups) => {
|
||||
const teaCups = [];
|
||||
|
||||
for(let cups = 1; cups <= numOfCups; cups += 1) {
|
||||
const teaCup = prepareTea();
|
||||
teaCups.push(teaCup);
|
||||
}
|
||||
return teaCups;
|
||||
};
|
||||
|
||||
// Only change code below this line
|
||||
const tea4GreenTeamFCC = null;
|
||||
const tea4BlackTeamFCC = null;
|
||||
// Only change code above this line
|
||||
|
||||
console.log(
|
||||
tea4GreenTeamFCC,
|
||||
tea4BlackTeamFCC
|
||||
);
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
const prepareGreenTea = () => 'greenTea';
|
||||
const prepareBlackTea = () => 'blackTea';
|
||||
|
||||
const getTea = (prepareTea, numOfCups) => {
|
||||
const teaCups = [];
|
||||
|
||||
for(let cups = 1; cups <= numOfCups; cups += 1) {
|
||||
const teaCup = prepareTea();
|
||||
teaCups.push(teaCup);
|
||||
}
|
||||
return teaCups;
|
||||
};
|
||||
|
||||
const tea4BlackTeamFCC = getTea(prepareBlackTea, 13);
|
||||
const tea4GreenTeamFCC = getTea(prepareGreenTea, 27);
|
||||
```
|
||||
@@ -0,0 +1,139 @@
|
||||
---
|
||||
id: 587d7b8e367417b2b2512b5d
|
||||
title: Verstehe die Gefahren der Verwendung von imperativem Code
|
||||
challengeType: 1
|
||||
forumTopicId: 301241
|
||||
dashedName: understand-the-hazards-of-using-imperative-code
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Funktionale Programmierung ist eine gute Angewohnheit. So bleibt dein Code einfach zu verwalten und du bist vor heimlichen Fehlern geschützt. Aber bevor wir dazu kommen, lass uns einen Blick auf einen imperativen Ansatz zur Programmierung werfen, um aufzuzeigen, wo du Probleme haben könntest.
|
||||
|
||||
Im Englischen (und in vielen anderen Sprachen) wird der Imperativ verwendet, um Befehle zu erteilen. Ähnlich verhält es sich mit einem imperativen Programmierstil, der dem Computer eine Reihe von Anweisungen zur Ausführung einer Aufgabe gibt.
|
||||
|
||||
Oftmals ändern die Anweisungen den Zustand des Programms, wie z. B. das Aktualisieren von globalen Variablen. Ein klassisches Beispiel ist das Schreiben einer `for`-Schleife, die genaue Anweisungen für die Iteration über die Indizes eines Arrays gibt.
|
||||
|
||||
Im Gegensatz dazu ist die funktionale Programmierung eine Form der deklarativen Programmierung. Du teilst dem Computer mit, was du tun willst, indem du eine Methode oder Funktion aufrufst.
|
||||
|
||||
JavaScript bietet viele vordefinierte Methoden für gängige Aufgaben, so dass du nicht schreiben musst, wie der Computer sie ausführen soll. Anstatt die oben erwähnte `for`-Schleife zu verwenden, könntest du zum Beispiel die `map`-Methode aufrufen, die die Details der Iteration über ein Array behandelt. Das hilft, semantische Fehler zu vermeiden, wie die "Off By One Error", die im Abschnitt Debugging behandelt wurden.
|
||||
|
||||
Stell dir folgendes Szenario vor: Du surfst in deinem Browser im Internet und möchtest die von dir geöffneten Tabs verfolgen. Versuchen wir, dies mit einem einfachen objektorientierten Code zu modellieren.
|
||||
|
||||
Ein Fensterobjekt besteht aus Registerkarten, und normalerweise hast du mehr als ein Fenster geöffnet. Die Titel der einzelnen geöffneten Seiten in jedem Window-Objekt werden in einem Array gespeichert. Nach der Arbeit im Browser (Öffnen neuer Tabs, Zusammenführen von Fenstern und Schließen von Tabs) möchtest du die noch offenen Tabs ausgeben. Geschlossene Tabs werden aus dem Array entfernt und neue Tabs werden (der Einfachheit halber) am Ende des Arrays hinzugefügt.
|
||||
|
||||
Der Code-Editor zeigt eine Implementierung dieser Funktionalität mit Funktionen für `tabOpen()`, `tabClose()` und `join()`. Das Array `tabs` ist Teil des Window-Objekts und speichert die Namen der geöffneten Seiten.
|
||||
|
||||
# --instructions--
|
||||
|
||||
Überprüfe den Code im Editor. Es wird eine Methode verwendet, die Nebenwirkungen im Programm hat und ein falsches Verhalten verursacht. Die endgültige Liste der geöffneten Tabs, die in `finalTabs.tabs` gespeichert wird, sollte `['FB', 'Gitter', 'Reddit', 'Twitter', 'Medium', 'new tab', 'Netflix', 'YouTube', 'Vine', 'GMail', 'Work mail', 'Docs', 'freeCodeCamp', 'new tab']` sein, aber die Liste, die der Code erzeugt, ist etwas anders.
|
||||
|
||||
Ändere `Window.prototype.tabClose` so, dass es die richtige Registerkarte entfernt.
|
||||
|
||||
# --hints--
|
||||
|
||||
`finalTabs.tabs` sollte wie folgt aussehen: `['FB', 'Gitter', 'Reddit', 'Twitter', 'Medium', 'new tab', 'Netflix', 'YouTube', 'Vine', 'GMail', 'Work mail', 'Docs', 'freeCodeCamp', 'new tab']`
|
||||
|
||||
```js
|
||||
assert.deepEqual(finalTabs.tabs, [
|
||||
'FB',
|
||||
'Gitter',
|
||||
'Reddit',
|
||||
'Twitter',
|
||||
'Medium',
|
||||
'new tab',
|
||||
'Netflix',
|
||||
'YouTube',
|
||||
'Vine',
|
||||
'GMail',
|
||||
'Work mail',
|
||||
'Docs',
|
||||
'freeCodeCamp',
|
||||
'new tab'
|
||||
]);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
// tabs is an array of titles of each site open within the window
|
||||
const Window = function(tabs) {
|
||||
this.tabs = tabs; // We keep a record of the array inside the object
|
||||
};
|
||||
|
||||
// When you join two windows into one window
|
||||
Window.prototype.join = function(otherWindow) {
|
||||
this.tabs = this.tabs.concat(otherWindow.tabs);
|
||||
return this;
|
||||
};
|
||||
|
||||
// When you open a new tab at the end
|
||||
Window.prototype.tabOpen = function(tab) {
|
||||
this.tabs.push('new tab'); // Let's open a new tab for now
|
||||
return this;
|
||||
};
|
||||
|
||||
// When you close a tab
|
||||
Window.prototype.tabClose = function(index) {
|
||||
|
||||
// Only change code below this line
|
||||
|
||||
const tabsBeforeIndex = this.tabs.splice(0, index); // Get the tabs before the tab
|
||||
const tabsAfterIndex = this.tabs.splice(index + 1); // Get the tabs after the tab
|
||||
|
||||
this.tabs = tabsBeforeIndex.concat(tabsAfterIndex); // Join them together
|
||||
|
||||
// Only change code above this line
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
// Let's create three browser windows
|
||||
const workWindow = new Window(['GMail', 'Inbox', 'Work mail', 'Docs', 'freeCodeCamp']); // Your mailbox, drive, and other work sites
|
||||
const socialWindow = new Window(['FB', 'Gitter', 'Reddit', 'Twitter', 'Medium']); // Social sites
|
||||
const videoWindow = new Window(['Netflix', 'YouTube', 'Vimeo', 'Vine']); // Entertainment sites
|
||||
|
||||
// Now perform the tab opening, closing, and other operations
|
||||
const finalTabs = socialWindow
|
||||
.tabOpen() // Open a new tab for cat memes
|
||||
.join(videoWindow.tabClose(2)) // Close third tab in video window, and join
|
||||
.join(workWindow.tabClose(1).tabOpen());
|
||||
console.log(finalTabs.tabs);
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
const Window = function(tabs) {
|
||||
this.tabs = tabs;
|
||||
};
|
||||
|
||||
Window.prototype.join = function(otherWindow) {
|
||||
this.tabs = this.tabs.concat(otherWindow.tabs);
|
||||
return this;
|
||||
};
|
||||
|
||||
Window.prototype.tabOpen = function(tab) {
|
||||
this.tabs.push('new tab');
|
||||
return this;
|
||||
};
|
||||
|
||||
Window.prototype.tabClose = function(index) {
|
||||
const tabsBeforeIndex = this.tabs.slice(0, index);
|
||||
const tabsAfterIndex = this.tabs.slice(index + 1);
|
||||
|
||||
this.tabs = tabsBeforeIndex.concat(tabsAfterIndex);
|
||||
return this;
|
||||
};
|
||||
|
||||
const workWindow = new Window(['GMail', 'Inbox', 'Work mail', 'Docs', 'freeCodeCamp']);
|
||||
const socialWindow = new Window(['FB', 'Gitter', 'Reddit', 'Twitter', 'Medium']);
|
||||
const videoWindow = new Window(['Netflix', 'YouTube', 'Vimeo', 'Vine']);
|
||||
|
||||
const finalTabs = socialWindow
|
||||
.tabOpen()
|
||||
.join(videoWindow.tabClose(2))
|
||||
.join(workWindow.tabClose(1).tabOpen());
|
||||
```
|
||||
@@ -0,0 +1,97 @@
|
||||
---
|
||||
id: 587d7b88367417b2b2512b45
|
||||
title: 'Verwende Funktionen höherer Ordnung map, filter oder reduce, um ein komplexes Problem zu lösen'
|
||||
challengeType: 1
|
||||
forumTopicId: 301311
|
||||
dashedName: use-higher-order-functions-map-filter-or-reduce-to-solve-a-complex-problem
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Nachdem du nun ein paar Aufgaben mit Funktionen höherer Ordnung wie `map()`, `filter()` und `reduce()` gelöst hast, kannst du sie jetzt anwenden, um eine komplexere Aufgabe zu lösen.
|
||||
|
||||
# --instructions--
|
||||
|
||||
Vervollständige den Code für die Funktion `squareList` mit einer beliebigen Kombination aus `map()`, `filter()` und `reduce()`. Die Funktion sollte ein neues Array zurückgeben, das die Quadratzahlen *nur* von den positiven ganzen Zahlen enthält (Dezimalzahlen sind keine ganzen Zahlen), wenn ihr ein Array mit reellen Zahlen übergeben wird. Ein Beispiel für ein Array mit reellen Zahlen ist `[-3, 4.8, 5, 3, -3.2]`.
|
||||
|
||||
**Hinweis:** Deine Funktion sollte weder `for` noch `while`-Schleifen oder die Funktion `forEach()` verwenden.
|
||||
|
||||
# --hints--
|
||||
|
||||
`squareList` sollte eine Funktion (`function`) sein.
|
||||
|
||||
```js
|
||||
assert.typeOf(squareList, 'function'),
|
||||
'<code>squareList</code> should be a <code>function</code>';
|
||||
```
|
||||
|
||||
`for`, `while` und `forEach` sollten nicht verwendet werden.
|
||||
|
||||
```js
|
||||
assert(!code.match(/for|while|forEach/g));
|
||||
```
|
||||
|
||||
`map`, `filter` oder `reduce` sollten verwendet werden.
|
||||
|
||||
```js
|
||||
assert(
|
||||
__helpers
|
||||
.removeWhiteSpace(code)
|
||||
.match(/\.(map|filter|reduce)\(/g)
|
||||
);
|
||||
```
|
||||
|
||||
Die Funktion sollte ein `array` zurückgeben.
|
||||
|
||||
```js
|
||||
assert(Array.isArray(squareList([4, 5.6, -9.8, 3.14, 42, 6, 8.34, -2])));
|
||||
```
|
||||
|
||||
`squareList([4, 5.6, -9.8, 3.14, 42, 6, 8.34, -2])` sollte `[16, 1764, 36]` zurückgeben.
|
||||
|
||||
```js
|
||||
assert.deepStrictEqual(squareList([4, 5.6, -9.8, 3.14, 42, 6, 8.34, -2]), [
|
||||
16,
|
||||
1764,
|
||||
36
|
||||
]);
|
||||
```
|
||||
|
||||
`squareList([-3.7, -5, 3, 10, 12.5, 7, -4.5, -17, 0.3])` sollte `[9, 100, 49]` zurückgeben.
|
||||
|
||||
```js
|
||||
assert.deepStrictEqual(squareList([-3.7, -5, 3, 10, 12.5, 7, -4.5, -17, 0.3]), [
|
||||
9,
|
||||
100,
|
||||
49
|
||||
]);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
const squareList = arr => {
|
||||
// Only change code below this line
|
||||
return arr;
|
||||
// Only change code above this line
|
||||
};
|
||||
|
||||
const squaredIntegers = squareList([-3, 4.8, 5, 3, -3.2]);
|
||||
console.log(squaredIntegers);
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
const squareList = arr => {
|
||||
const positiveIntegers = arr.filter(num => {
|
||||
return num >= 0 && Number.isInteger(num);
|
||||
});
|
||||
const squaredIntegers = positiveIntegers.map(num => {
|
||||
return num ** 2;
|
||||
});
|
||||
return squaredIntegers;
|
||||
};
|
||||
```
|
||||
@@ -0,0 +1,76 @@
|
||||
---
|
||||
id: 587d7dab367417b2b2512b6e
|
||||
title: Prüfe mit der Methode every, ob jedes Element in einem Array ein Kriterium erfüllt
|
||||
challengeType: 1
|
||||
forumTopicId: 301312
|
||||
dashedName: use-the-every-method-to-check-that-every-element-in-an-array-meets-a-criteria
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Die Methode `every` arbeitet mit Arrays, um zu prüfen, ob *jedes* Element einen bestimmten Test besteht. Sie gibt einen booleschen Wert zurück - `true`, wenn alle Werte die Kriterien erfüllen, `false`, wenn nicht.
|
||||
|
||||
Der folgende Code würde zum Beispiel prüfen, ob jedes Element im Array `numbers` kleiner als 10 ist:
|
||||
|
||||
```js
|
||||
const numbers = [1, 5, 8, 0, 10, 11];
|
||||
|
||||
numbers.every(function(currentValue) {
|
||||
return currentValue < 10;
|
||||
});
|
||||
```
|
||||
|
||||
Die Methode `every` würde hier `false` zurückgeben.
|
||||
|
||||
# --instructions--
|
||||
|
||||
Verwende die Methode `every` innerhalb der Funktion `checkPositive`, um zu prüfen, ob jedes Element in `arr` positiv ist. Die Funktion sollte einen booleschen Wert zurückgeben.
|
||||
|
||||
# --hints--
|
||||
|
||||
Dein Code sollte die Methode `every` verwenden.
|
||||
|
||||
```js
|
||||
assert(code.match(/\.every/g));
|
||||
```
|
||||
|
||||
`checkPositive([1, 2, 3, -4, 5])` sollte `false` zurückgeben.
|
||||
|
||||
```js
|
||||
assert.isFalse(checkPositive([1, 2, 3, -4, 5]));
|
||||
```
|
||||
|
||||
`checkPositive([1, 2, 3, 4, 5])` sollte `true` zurückgeben.
|
||||
|
||||
```js
|
||||
assert.isTrue(checkPositive([1, 2, 3, 4, 5]));
|
||||
```
|
||||
|
||||
`checkPositive([1, -2, 3, -4, 5])` sollte `false` zurückgeben.
|
||||
|
||||
```js
|
||||
assert.isFalse(checkPositive([1, -2, 3, -4, 5]));
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function checkPositive(arr) {
|
||||
// Only change code below this line
|
||||
|
||||
|
||||
// Only change code above this line
|
||||
}
|
||||
|
||||
checkPositive([1, 2, 3, -4, 5]);
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function checkPositive(arr) {
|
||||
return arr.every(num => num > 0);
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,314 @@
|
||||
---
|
||||
id: 587d7b8f367417b2b2512b63
|
||||
title: Verwende die Filtermethode, um Daten aus einem Array zu extrahieren
|
||||
challengeType: 1
|
||||
forumTopicId: 18179
|
||||
dashedName: use-the-filter-method-to-extract-data-from-an-array
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Eine weitere nützliche Array-Funktion ist `Array.prototype.filter()`, oder einfach `filter()`.
|
||||
|
||||
`filter` ruft eine Funktion für jedes Element eines Arrays auf und gibt ein neues Array zurück, das nur die Elemente enthält, für die die Funktion `true` zurückgibt. Mit anderen Worten: Sie filtert das Array auf der Grundlage der übergebenen Funktion. Genau wie `map` macht sie das, ohne dass das ursprüngliche Array verändert werden muss.
|
||||
|
||||
Die Callback-Funktion nimmt drei Argumente entgegen. Das erste Argument ist das aktuelle Element, das bearbeitet wird. Das zweite ist der Index dieses Elements und das dritte ist das Array, auf dem die Methode `filter` aufgerufen wurde.
|
||||
|
||||
Unten findest du ein Beispiel, in dem du die Methode `filter` auf das Array `users` anwendest, um ein neues Array zu erstellen, das nur die Benutzer unter 30 Jahren enthält. Der Einfachheit halber wird im Beispiel nur das erste Argument des Callbacks verwendet.
|
||||
|
||||
```js
|
||||
const users = [
|
||||
{ name: 'John', age: 34 },
|
||||
{ name: 'Amy', age: 20 },
|
||||
{ name: 'camperCat', age: 10 }
|
||||
];
|
||||
|
||||
const usersUnder30 = users.filter(user => user.age < 30);
|
||||
console.log(usersUnder30);
|
||||
```
|
||||
|
||||
Die Konsole würde den Wert `[ { name: 'Amy', age: 20 }, { name: 'camperCat', age: 10 } ]` anzeigen.
|
||||
|
||||
# --instructions--
|
||||
|
||||
Die Variable `watchList` enthält ein Array von Objekten mit Informationen über verschiedene Filme. Wende eine Kombination aus `filter` und `map` auf `watchList` an, um ein neues Array von Objekten nur mit den Keys `title` und `rating` zuzuweisen. Das neue Array sollte nur Objekte enthalten, deren `imdbRating` größer oder gleich 8.0 ist. Beachte, dass die `rating`-Werte als Strings im Objekt gespeichert werden und du sie eventuell in Zahlen umwandeln musst, um mathematische Operationen mit ihnen durchzuführen.
|
||||
|
||||
# --hints--
|
||||
|
||||
Die Variable `watchList` sollte sich nicht ändern.
|
||||
|
||||
```js
|
||||
assert(
|
||||
watchList[0].Title === 'Inception' && watchList[4].Director == 'James Cameron'
|
||||
);
|
||||
```
|
||||
|
||||
Dein Code sollte die Methode `filter` verwenden.
|
||||
|
||||
```js
|
||||
assert(code.match(/\s*\.\s*filter/g));
|
||||
```
|
||||
|
||||
Dein Code sollte keine `for`-Schleife verwenden.
|
||||
|
||||
```js
|
||||
assert(!code.match(/for\s*?\([\s\S]*?\)/g));
|
||||
```
|
||||
|
||||
`filteredList` sollt gleich `[{"title": "Inception", "rating": "8.8"}, {"title": "Interstellar", "rating": "8.6"}, {"title": "The Dark Knight", "rating": "9.0"}, {"title": "Batman Begins", "rating": "8.3"}]` sein.
|
||||
|
||||
```js
|
||||
assert.deepEqual(filteredList, [
|
||||
{ title: 'Inception', rating: '8.8' },
|
||||
{ title: 'Interstellar', rating: '8.6' },
|
||||
{ title: 'The Dark Knight', rating: '9.0' },
|
||||
{ title: 'Batman Begins', rating: '8.3' }
|
||||
]);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
// The global variable
|
||||
const watchList = [
|
||||
{
|
||||
"Title": "Inception",
|
||||
"Year": "2010",
|
||||
"Rated": "PG-13",
|
||||
"Released": "16 Jul 2010",
|
||||
"Runtime": "148 min",
|
||||
"Genre": "Action, Adventure, Crime",
|
||||
"Director": "Christopher Nolan",
|
||||
"Writer": "Christopher Nolan",
|
||||
"Actors": "Leonardo DiCaprio, Joseph Gordon-Levitt, Elliot Page, Tom Hardy",
|
||||
"Plot": "A thief, who steals corporate secrets through use of dream-sharing technology, is given the inverse task of planting an idea into the mind of a CEO.",
|
||||
"Language": "English, Japanese, French",
|
||||
"Country": "USA, UK",
|
||||
"Awards": "Won 4 Oscars. Another 143 wins & 198 nominations.",
|
||||
"Poster": "http://ia.media-imdb.com/images/M/MV5BMjAxMzY3NjcxNF5BMl5BanBnXkFtZTcwNTI5OTM0Mw@@._V1_SX300.jpg",
|
||||
"Metascore": "74",
|
||||
"imdbRating": "8.8",
|
||||
"imdbVotes": "1,446,708",
|
||||
"imdbID": "tt1375666",
|
||||
"Type": "movie",
|
||||
"Response": "True"
|
||||
},
|
||||
{
|
||||
"Title": "Interstellar",
|
||||
"Year": "2014",
|
||||
"Rated": "PG-13",
|
||||
"Released": "07 Nov 2014",
|
||||
"Runtime": "169 min",
|
||||
"Genre": "Adventure, Drama, Sci-Fi",
|
||||
"Director": "Christopher Nolan",
|
||||
"Writer": "Jonathan Nolan, Christopher Nolan",
|
||||
"Actors": "Ellen Burstyn, Matthew McConaughey, Mackenzie Foy, John Lithgow",
|
||||
"Plot": "A team of explorers travel through a wormhole in space in an attempt to ensure humanity's survival.",
|
||||
"Language": "English",
|
||||
"Country": "USA, UK",
|
||||
"Awards": "Won 1 Oscar. Another 39 wins & 132 nominations.",
|
||||
"Poster": "http://ia.media-imdb.com/images/M/MV5BMjIxNTU4MzY4MF5BMl5BanBnXkFtZTgwMzM4ODI3MjE@._V1_SX300.jpg",
|
||||
"Metascore": "74",
|
||||
"imdbRating": "8.6",
|
||||
"imdbVotes": "910,366",
|
||||
"imdbID": "tt0816692",
|
||||
"Type": "movie",
|
||||
"Response": "True"
|
||||
},
|
||||
{
|
||||
"Title": "The Dark Knight",
|
||||
"Year": "2008",
|
||||
"Rated": "PG-13",
|
||||
"Released": "18 Jul 2008",
|
||||
"Runtime": "152 min",
|
||||
"Genre": "Action, Adventure, Crime",
|
||||
"Director": "Christopher Nolan",
|
||||
"Writer": "Jonathan Nolan (screenplay), Christopher Nolan (screenplay), Christopher Nolan (story), David S. Goyer (story), Bob Kane (characters)",
|
||||
"Actors": "Christian Bale, Heath Ledger, Aaron Eckhart, Michael Caine",
|
||||
"Plot": "When the menace known as the Joker wreaks havoc and chaos on the people of Gotham, the caped crusader must come to terms with one of the greatest psychological tests of his ability to fight injustice.",
|
||||
"Language": "English, Mandarin",
|
||||
"Country": "USA, UK",
|
||||
"Awards": "Won 2 Oscars. Another 146 wins & 142 nominations.",
|
||||
"Poster": "http://ia.media-imdb.com/images/M/MV5BMTMxNTMwODM0NF5BMl5BanBnXkFtZTcwODAyMTk2Mw@@._V1_SX300.jpg",
|
||||
"Metascore": "82",
|
||||
"imdbRating": "9.0",
|
||||
"imdbVotes": "1,652,832",
|
||||
"imdbID": "tt0468569",
|
||||
"Type": "movie",
|
||||
"Response": "True"
|
||||
},
|
||||
{
|
||||
"Title": "Batman Begins",
|
||||
"Year": "2005",
|
||||
"Rated": "PG-13",
|
||||
"Released": "15 Jun 2005",
|
||||
"Runtime": "140 min",
|
||||
"Genre": "Action, Adventure",
|
||||
"Director": "Christopher Nolan",
|
||||
"Writer": "Bob Kane (characters), David S. Goyer (story), Christopher Nolan (screenplay), David S. Goyer (screenplay)",
|
||||
"Actors": "Christian Bale, Michael Caine, Liam Neeson, Katie Holmes",
|
||||
"Plot": "After training with his mentor, Batman begins his fight to free crime-ridden Gotham City from the corruption that Scarecrow and the League of Shadows have cast upon it.",
|
||||
"Language": "English, Urdu, Mandarin",
|
||||
"Country": "USA, UK",
|
||||
"Awards": "Nominated for 1 Oscar. Another 15 wins & 66 nominations.",
|
||||
"Poster": "http://ia.media-imdb.com/images/M/MV5BNTM3OTc0MzM2OV5BMl5BanBnXkFtZTYwNzUwMTI3._V1_SX300.jpg",
|
||||
"Metascore": "70",
|
||||
"imdbRating": "8.3",
|
||||
"imdbVotes": "972,584",
|
||||
"imdbID": "tt0372784",
|
||||
"Type": "movie",
|
||||
"Response": "True"
|
||||
},
|
||||
{
|
||||
"Title": "Avatar",
|
||||
"Year": "2009",
|
||||
"Rated": "PG-13",
|
||||
"Released": "18 Dec 2009",
|
||||
"Runtime": "162 min",
|
||||
"Genre": "Action, Adventure, Fantasy",
|
||||
"Director": "James Cameron",
|
||||
"Writer": "James Cameron",
|
||||
"Actors": "Sam Worthington, Zoe Saldana, Sigourney Weaver, Stephen Lang",
|
||||
"Plot": "A paraplegic marine dispatched to the moon Pandora on a unique mission becomes torn between following his orders and protecting the world he feels is his home.",
|
||||
"Language": "English, Spanish",
|
||||
"Country": "USA, UK",
|
||||
"Awards": "Won 3 Oscars. Another 80 wins & 121 nominations.",
|
||||
"Poster": "http://ia.media-imdb.com/images/M/MV5BMTYwOTEwNjAzMl5BMl5BanBnXkFtZTcwODc5MTUwMw@@._V1_SX300.jpg",
|
||||
"Metascore": "83",
|
||||
"imdbRating": "7.9",
|
||||
"imdbVotes": "876,575",
|
||||
"imdbID": "tt0499549",
|
||||
"Type": "movie",
|
||||
"Response": "True"
|
||||
}
|
||||
];
|
||||
|
||||
// Only change code below this line
|
||||
|
||||
const filteredList = "";
|
||||
|
||||
// Only change code above this line
|
||||
|
||||
console.log(filteredList);
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
const watchList = [
|
||||
{
|
||||
"Title": "Inception",
|
||||
"Year": "2010",
|
||||
"Rated": "PG-13",
|
||||
"Released": "16 Jul 2010",
|
||||
"Runtime": "148 min",
|
||||
"Genre": "Action, Adventure, Crime",
|
||||
"Director": "Christopher Nolan",
|
||||
"Writer": "Christopher Nolan",
|
||||
"Actors": "Leonardo DiCaprio, Joseph Gordon-Levitt, Elliot Page, Tom Hardy",
|
||||
"Plot": "A thief, who steals corporate secrets through use of dream-sharing technology, is given the inverse task of planting an idea into the mind of a CEO.",
|
||||
"Language": "English, Japanese, French",
|
||||
"Country": "USA, UK",
|
||||
"Awards": "Won 4 Oscars. Another 143 wins & 198 nominations.",
|
||||
"Poster": "http://ia.media-imdb.com/images/M/MV5BMjAxMzY3NjcxNF5BMl5BanBnXkFtZTcwNTI5OTM0Mw@@._V1_SX300.jpg",
|
||||
"Metascore": "74",
|
||||
"imdbRating": "8.8",
|
||||
"imdbVotes": "1,446,708",
|
||||
"imdbID": "tt1375666",
|
||||
"Type": "movie",
|
||||
"Response": "True"
|
||||
},
|
||||
{
|
||||
"Title": "Interstellar",
|
||||
"Year": "2014",
|
||||
"Rated": "PG-13",
|
||||
"Released": "07 Nov 2014",
|
||||
"Runtime": "169 min",
|
||||
"Genre": "Adventure, Drama, Sci-Fi",
|
||||
"Director": "Christopher Nolan",
|
||||
"Writer": "Jonathan Nolan, Christopher Nolan",
|
||||
"Actors": "Ellen Burstyn, Matthew McConaughey, Mackenzie Foy, John Lithgow",
|
||||
"Plot": "A team of explorers travel through a wormhole in space in an attempt to ensure humanity's survival.",
|
||||
"Language": "English",
|
||||
"Country": "USA, UK",
|
||||
"Awards": "Won 1 Oscar. Another 39 wins & 132 nominations.",
|
||||
"Poster": "http://ia.media-imdb.com/images/M/MV5BMjIxNTU4MzY4MF5BMl5BanBnXkFtZTgwMzM4ODI3MjE@._V1_SX300.jpg",
|
||||
"Metascore": "74",
|
||||
"imdbRating": "8.6",
|
||||
"imdbVotes": "910,366",
|
||||
"imdbID": "tt0816692",
|
||||
"Type": "movie",
|
||||
"Response": "True"
|
||||
},
|
||||
{
|
||||
"Title": "The Dark Knight",
|
||||
"Year": "2008",
|
||||
"Rated": "PG-13",
|
||||
"Released": "18 Jul 2008",
|
||||
"Runtime": "152 min",
|
||||
"Genre": "Action, Adventure, Crime",
|
||||
"Director": "Christopher Nolan",
|
||||
"Writer": "Jonathan Nolan (screenplay), Christopher Nolan (screenplay), Christopher Nolan (story), David S. Goyer (story), Bob Kane (characters)",
|
||||
"Actors": "Christian Bale, Heath Ledger, Aaron Eckhart, Michael Caine",
|
||||
"Plot": "When the menace known as the Joker wreaks havoc and chaos on the people of Gotham, the caped crusader must come to terms with one of the greatest psychological tests of his ability to fight injustice.",
|
||||
"Language": "English, Mandarin",
|
||||
"Country": "USA, UK",
|
||||
"Awards": "Won 2 Oscars. Another 146 wins & 142 nominations.",
|
||||
"Poster": "http://ia.media-imdb.com/images/M/MV5BMTMxNTMwODM0NF5BMl5BanBnXkFtZTcwODAyMTk2Mw@@._V1_SX300.jpg",
|
||||
"Metascore": "82",
|
||||
"imdbRating": "9.0",
|
||||
"imdbVotes": "1,652,832",
|
||||
"imdbID": "tt0468569",
|
||||
"Type": "movie",
|
||||
"Response": "True"
|
||||
},
|
||||
{
|
||||
"Title": "Batman Begins",
|
||||
"Year": "2005",
|
||||
"Rated": "PG-13",
|
||||
"Released": "15 Jun 2005",
|
||||
"Runtime": "140 min",
|
||||
"Genre": "Action, Adventure",
|
||||
"Director": "Christopher Nolan",
|
||||
"Writer": "Bob Kane (characters), David S. Goyer (story), Christopher Nolan (screenplay), David S. Goyer (screenplay)",
|
||||
"Actors": "Christian Bale, Michael Caine, Liam Neeson, Katie Holmes",
|
||||
"Plot": "After training with his mentor, Batman begins his fight to free crime-ridden Gotham City from the corruption that Scarecrow and the League of Shadows have cast upon it.",
|
||||
"Language": "English, Urdu, Mandarin",
|
||||
"Country": "USA, UK",
|
||||
"Awards": "Nominated for 1 Oscar. Another 15 wins & 66 nominations.",
|
||||
"Poster": "http://ia.media-imdb.com/images/M/MV5BNTM3OTc0MzM2OV5BMl5BanBnXkFtZTYwNzUwMTI3._V1_SX300.jpg",
|
||||
"Metascore": "70",
|
||||
"imdbRating": "8.3",
|
||||
"imdbVotes": "972,584",
|
||||
"imdbID": "tt0372784",
|
||||
"Type": "movie",
|
||||
"Response": "True"
|
||||
},
|
||||
{
|
||||
"Title": "Avatar",
|
||||
"Year": "2009",
|
||||
"Rated": "PG-13",
|
||||
"Released": "18 Dec 2009",
|
||||
"Runtime": "162 min",
|
||||
"Genre": "Action, Adventure, Fantasy",
|
||||
"Director": "James Cameron",
|
||||
"Writer": "James Cameron",
|
||||
"Actors": "Sam Worthington, Zoe Saldana, Sigourney Weaver, Stephen Lang",
|
||||
"Plot": "A paraplegic marine dispatched to the moon Pandora on a unique mission becomes torn between following his orders and protecting the world he feels is his home.",
|
||||
"Language": "English, Spanish",
|
||||
"Country": "USA, UK",
|
||||
"Awards": "Won 3 Oscars. Another 80 wins & 121 nominations.",
|
||||
"Poster": "http://ia.media-imdb.com/images/M/MV5BMTYwOTEwNjAzMl5BMl5BanBnXkFtZTcwODc5MTUwMw@@._V1_SX300.jpg",
|
||||
"Metascore": "83",
|
||||
"imdbRating": "7.9",
|
||||
"imdbVotes": "876,575",
|
||||
"imdbID": "tt0499549",
|
||||
"Type": "movie",
|
||||
"Response": "True"
|
||||
}
|
||||
];
|
||||
|
||||
const filteredList = watchList.filter(e => e.imdbRating >= 8).map( ({Title: title, imdbRating: rating}) => ({title, rating}) );
|
||||
```
|
||||
@@ -0,0 +1,329 @@
|
||||
---
|
||||
id: 587d7b8f367417b2b2512b61
|
||||
title: Verwende die map-Methode, um Daten aus einem Array zu extrahieren
|
||||
challengeType: 1
|
||||
forumTopicId: 18214
|
||||
dashedName: use-the-map-method-to-extract-data-from-an-array
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Bis jetzt haben wir gelernt, reine Funktionen zu verwenden, um Nebeneffekte in einem Programm zu vermeiden. Außerdem haben wir gesehen, wie wichtig es ist, dass eine Funktion nur von ihren Eingabeargumenten abhängt.
|
||||
|
||||
Das ist erst der Anfang. Wie der Name schon sagt, geht es bei der funktionalen Programmierung um eine Theorie der Funktionen.
|
||||
|
||||
Es wäre sinnvoll, sie als Argumente an andere Funktionen zu übergeben und eine Funktion von einer anderen Funktion zurückzugeben. Funktionen gelten in JavaScript als <dfn>Objekte erster Klasse</dfn>, d. h. sie können wie jedes andere Objekt verwendet werden. Sie können in Variablen gespeichert, in einem Objekt abgelegt oder als Funktionsargumente übergeben werden.
|
||||
|
||||
Beginnen wir mit einigen einfachen Array-Funktionen, die Methoden für den Prototyp des Array-Objekts sind. In dieser Übung schauen wir uns `Array.prototype.map()` an, oder einfacher `map`.
|
||||
|
||||
Die Methode `map` durchläuft jedes Element in einem Array und gibt ein neues Array zurück, das die Ergebnisse des Aufrufs der Callback-Funktion für jedes Element enthält. Dies geschieht, ohne dass das ursprüngliche Array verändert wird.
|
||||
|
||||
Wenn der Callback verwendet wird, werden ihm drei Argumente übergeben. Das erste Argument ist das aktuelle Element, das bearbeitet wird. Das zweite ist der Index dieses Elements und das dritte ist das Array, auf dem die Methode `map` aufgerufen wurde.
|
||||
|
||||
Unten findest du ein Beispiel, in dem du die Methode `map` auf das Array `users` anwendest, um ein neues Array zu erstellen, das nur die Namen der Benutzer als Elemente enthält. Der Einfachheit halber wird im Beispiel nur das erste Argument des Callbacks verwendet.
|
||||
|
||||
```js
|
||||
const users = [
|
||||
{ name: 'John', age: 34 },
|
||||
{ name: 'Amy', age: 20 },
|
||||
{ name: 'camperCat', age: 10 }
|
||||
];
|
||||
|
||||
const names = users.map(user => user.name);
|
||||
console.log(names);
|
||||
```
|
||||
|
||||
Die Konsole würde den Wert `[ 'John', 'Amy', 'camperCat' ]` ausgeben.
|
||||
|
||||
# --instructions--
|
||||
|
||||
Das Array `watchList` enthält Objekte mit Informationen über verschiedene Filme. Verwende `map` auf `watchList`, um der Variablen `ratings` ein neues Array von Objekten zuzuweisen. Jeder Film im neuen Array sollte nur einen Key `title` mit dem Namen des Films und einen Key `rating` mit der IMDB-Bewertung besitzen. Der Code im Editor verwendet dafür eine `for`-Schleife. Du solltest also die Schleifenfunktion durch deinen `map`-Ausdruck ersetzen.
|
||||
|
||||
# --hints--
|
||||
|
||||
Die Variable `watchList` sollte sich nicht ändern.
|
||||
|
||||
```js
|
||||
assert(
|
||||
watchList[0].Title === 'Inception' && watchList[4].Director == 'James Cameron'
|
||||
);
|
||||
```
|
||||
|
||||
Dein Code sollte keine `for`-Schleife verwenden.
|
||||
|
||||
```js
|
||||
assert(!code.match(/for\s*?\([\s\S]*?\)/));
|
||||
```
|
||||
|
||||
Dein Code sollte die Methode `map` verwenden.
|
||||
|
||||
```js
|
||||
assert(code.match(/\.map/g));
|
||||
```
|
||||
|
||||
`ratings` sollte gleich `[{"title": "Inception", "rating": "8.8"}, {"title": "Interstellar", "rating": "8.6"}, {"title": "The Dark Knight", "rating": "9.0"},{"title": "Batman Begins", "rating": "8.3"}, {"title": "Avatar", "rating": "7.9"}]` sein.
|
||||
|
||||
```js
|
||||
assert.deepEqual(ratings, [
|
||||
{ title: 'Inception', rating: '8.8' },
|
||||
{ title: 'Interstellar', rating: '8.6' },
|
||||
{ title: 'The Dark Knight', rating: '9.0' },
|
||||
{ title: 'Batman Begins', rating: '8.3' },
|
||||
{ title: 'Avatar', rating: '7.9' }
|
||||
]);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
// The global variable
|
||||
const watchList = [
|
||||
{
|
||||
"Title": "Inception",
|
||||
"Year": "2010",
|
||||
"Rated": "PG-13",
|
||||
"Released": "16 Jul 2010",
|
||||
"Runtime": "148 min",
|
||||
"Genre": "Action, Adventure, Crime",
|
||||
"Director": "Christopher Nolan",
|
||||
"Writer": "Christopher Nolan",
|
||||
"Actors": "Leonardo DiCaprio, Joseph Gordon-Levitt, Elliot Page, Tom Hardy",
|
||||
"Plot": "A thief, who steals corporate secrets through use of dream-sharing technology, is given the inverse task of planting an idea into the mind of a CEO.",
|
||||
"Language": "English, Japanese, French",
|
||||
"Country": "USA, UK",
|
||||
"Awards": "Won 4 Oscars. Another 143 wins & 198 nominations.",
|
||||
"Poster": "http://ia.media-imdb.com/images/M/MV5BMjAxMzY3NjcxNF5BMl5BanBnXkFtZTcwNTI5OTM0Mw@@._V1_SX300.jpg",
|
||||
"Metascore": "74",
|
||||
"imdbRating": "8.8",
|
||||
"imdbVotes": "1,446,708",
|
||||
"imdbID": "tt1375666",
|
||||
"Type": "movie",
|
||||
"Response": "True"
|
||||
},
|
||||
{
|
||||
"Title": "Interstellar",
|
||||
"Year": "2014",
|
||||
"Rated": "PG-13",
|
||||
"Released": "07 Nov 2014",
|
||||
"Runtime": "169 min",
|
||||
"Genre": "Adventure, Drama, Sci-Fi",
|
||||
"Director": "Christopher Nolan",
|
||||
"Writer": "Jonathan Nolan, Christopher Nolan",
|
||||
"Actors": "Ellen Burstyn, Matthew McConaughey, Mackenzie Foy, John Lithgow",
|
||||
"Plot": "A team of explorers travel through a wormhole in space in an attempt to ensure humanity's survival.",
|
||||
"Language": "English",
|
||||
"Country": "USA, UK",
|
||||
"Awards": "Won 1 Oscar. Another 39 wins & 132 nominations.",
|
||||
"Poster": "http://ia.media-imdb.com/images/M/MV5BMjIxNTU4MzY4MF5BMl5BanBnXkFtZTgwMzM4ODI3MjE@._V1_SX300.jpg",
|
||||
"Metascore": "74",
|
||||
"imdbRating": "8.6",
|
||||
"imdbVotes": "910,366",
|
||||
"imdbID": "tt0816692",
|
||||
"Type": "movie",
|
||||
"Response": "True"
|
||||
},
|
||||
{
|
||||
"Title": "The Dark Knight",
|
||||
"Year": "2008",
|
||||
"Rated": "PG-13",
|
||||
"Released": "18 Jul 2008",
|
||||
"Runtime": "152 min",
|
||||
"Genre": "Action, Adventure, Crime",
|
||||
"Director": "Christopher Nolan",
|
||||
"Writer": "Jonathan Nolan (screenplay), Christopher Nolan (screenplay), Christopher Nolan (story), David S. Goyer (story), Bob Kane (characters)",
|
||||
"Actors": "Christian Bale, Heath Ledger, Aaron Eckhart, Michael Caine",
|
||||
"Plot": "When the menace known as the Joker wreaks havoc and chaos on the people of Gotham, the caped crusader must come to terms with one of the greatest psychological tests of his ability to fight injustice.",
|
||||
"Language": "English, Mandarin",
|
||||
"Country": "USA, UK",
|
||||
"Awards": "Won 2 Oscars. Another 146 wins & 142 nominations.",
|
||||
"Poster": "http://ia.media-imdb.com/images/M/MV5BMTMxNTMwODM0NF5BMl5BanBnXkFtZTcwODAyMTk2Mw@@._V1_SX300.jpg",
|
||||
"Metascore": "82",
|
||||
"imdbRating": "9.0",
|
||||
"imdbVotes": "1,652,832",
|
||||
"imdbID": "tt0468569",
|
||||
"Type": "movie",
|
||||
"Response": "True"
|
||||
},
|
||||
{
|
||||
"Title": "Batman Begins",
|
||||
"Year": "2005",
|
||||
"Rated": "PG-13",
|
||||
"Released": "15 Jun 2005",
|
||||
"Runtime": "140 min",
|
||||
"Genre": "Action, Adventure",
|
||||
"Director": "Christopher Nolan",
|
||||
"Writer": "Bob Kane (characters), David S. Goyer (story), Christopher Nolan (screenplay), David S. Goyer (screenplay)",
|
||||
"Actors": "Christian Bale, Michael Caine, Liam Neeson, Katie Holmes",
|
||||
"Plot": "After training with his mentor, Batman begins his fight to free crime-ridden Gotham City from the corruption that Scarecrow and the League of Shadows have cast upon it.",
|
||||
"Language": "English, Urdu, Mandarin",
|
||||
"Country": "USA, UK",
|
||||
"Awards": "Nominated for 1 Oscar. Another 15 wins & 66 nominations.",
|
||||
"Poster": "http://ia.media-imdb.com/images/M/MV5BNTM3OTc0MzM2OV5BMl5BanBnXkFtZTYwNzUwMTI3._V1_SX300.jpg",
|
||||
"Metascore": "70",
|
||||
"imdbRating": "8.3",
|
||||
"imdbVotes": "972,584",
|
||||
"imdbID": "tt0372784",
|
||||
"Type": "movie",
|
||||
"Response": "True"
|
||||
},
|
||||
{
|
||||
"Title": "Avatar",
|
||||
"Year": "2009",
|
||||
"Rated": "PG-13",
|
||||
"Released": "18 Dec 2009",
|
||||
"Runtime": "162 min",
|
||||
"Genre": "Action, Adventure, Fantasy",
|
||||
"Director": "James Cameron",
|
||||
"Writer": "James Cameron",
|
||||
"Actors": "Sam Worthington, Zoe Saldana, Sigourney Weaver, Stephen Lang",
|
||||
"Plot": "A paraplegic marine dispatched to the moon Pandora on a unique mission becomes torn between following his orders and protecting the world he feels is his home.",
|
||||
"Language": "English, Spanish",
|
||||
"Country": "USA, UK",
|
||||
"Awards": "Won 3 Oscars. Another 80 wins & 121 nominations.",
|
||||
"Poster": "http://ia.media-imdb.com/images/M/MV5BMTYwOTEwNjAzMl5BMl5BanBnXkFtZTcwODc5MTUwMw@@._V1_SX300.jpg",
|
||||
"Metascore": "83",
|
||||
"imdbRating": "7.9",
|
||||
"imdbVotes": "876,575",
|
||||
"imdbID": "tt0499549",
|
||||
"Type": "movie",
|
||||
"Response": "True"
|
||||
}
|
||||
];
|
||||
|
||||
// Only change code below this line
|
||||
|
||||
const ratings = [];
|
||||
for (let i = 0; i < watchList.length; i++) {
|
||||
ratings.push({title: watchList[i]["Title"], rating: watchList[i]["imdbRating"]});
|
||||
}
|
||||
|
||||
// Only change code above this line
|
||||
|
||||
console.log(JSON.stringify(ratings));
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
const watchList = [
|
||||
{
|
||||
"Title": "Inception",
|
||||
"Year": "2010",
|
||||
"Rated": "PG-13",
|
||||
"Released": "16 Jul 2010",
|
||||
"Runtime": "148 min",
|
||||
"Genre": "Action, Adventure, Crime",
|
||||
"Director": "Christopher Nolan",
|
||||
"Writer": "Christopher Nolan",
|
||||
"Actors": "Leonardo DiCaprio, Joseph Gordon-Levitt, Elliot Page, Tom Hardy",
|
||||
"Plot": "A thief, who steals corporate secrets through use of dream-sharing technology, is given the inverse task of planting an idea into the mind of a CEO.",
|
||||
"Language": "English, Japanese, French",
|
||||
"Country": "USA, UK",
|
||||
"Awards": "Won 4 Oscars. Another 143 wins & 198 nominations.",
|
||||
"Poster": "http://ia.media-imdb.com/images/M/MV5BMjAxMzY3NjcxNF5BMl5BanBnXkFtZTcwNTI5OTM0Mw@@._V1_SX300.jpg",
|
||||
"Metascore": "74",
|
||||
"imdbRating": "8.8",
|
||||
"imdbVotes": "1,446,708",
|
||||
"imdbID": "tt1375666",
|
||||
"Type": "movie",
|
||||
"Response": "True"
|
||||
},
|
||||
{
|
||||
"Title": "Interstellar",
|
||||
"Year": "2014",
|
||||
"Rated": "PG-13",
|
||||
"Released": "07 Nov 2014",
|
||||
"Runtime": "169 min",
|
||||
"Genre": "Adventure, Drama, Sci-Fi",
|
||||
"Director": "Christopher Nolan",
|
||||
"Writer": "Jonathan Nolan, Christopher Nolan",
|
||||
"Actors": "Ellen Burstyn, Matthew McConaughey, Mackenzie Foy, John Lithgow",
|
||||
"Plot": "A team of explorers travel through a wormhole in space in an attempt to ensure humanity's survival.",
|
||||
"Language": "English",
|
||||
"Country": "USA, UK",
|
||||
"Awards": "Won 1 Oscar. Another 39 wins & 132 nominations.",
|
||||
"Poster": "http://ia.media-imdb.com/images/M/MV5BMjIxNTU4MzY4MF5BMl5BanBnXkFtZTgwMzM4ODI3MjE@._V1_SX300.jpg",
|
||||
"Metascore": "74",
|
||||
"imdbRating": "8.6",
|
||||
"imdbVotes": "910,366",
|
||||
"imdbID": "tt0816692",
|
||||
"Type": "movie",
|
||||
"Response": "True"
|
||||
},
|
||||
{
|
||||
"Title": "The Dark Knight",
|
||||
"Year": "2008",
|
||||
"Rated": "PG-13",
|
||||
"Released": "18 Jul 2008",
|
||||
"Runtime": "152 min",
|
||||
"Genre": "Action, Adventure, Crime",
|
||||
"Director": "Christopher Nolan",
|
||||
"Writer": "Jonathan Nolan (screenplay), Christopher Nolan (screenplay), Christopher Nolan (story), David S. Goyer (story), Bob Kane (characters)",
|
||||
"Actors": "Christian Bale, Heath Ledger, Aaron Eckhart, Michael Caine",
|
||||
"Plot": "When the menace known as the Joker wreaks havoc and chaos on the people of Gotham, the caped crusader must come to terms with one of the greatest psychological tests of his ability to fight injustice.",
|
||||
"Language": "English, Mandarin",
|
||||
"Country": "USA, UK",
|
||||
"Awards": "Won 2 Oscars. Another 146 wins & 142 nominations.",
|
||||
"Poster": "http://ia.media-imdb.com/images/M/MV5BMTMxNTMwODM0NF5BMl5BanBnXkFtZTcwODAyMTk2Mw@@._V1_SX300.jpg",
|
||||
"Metascore": "82",
|
||||
"imdbRating": "9.0",
|
||||
"imdbVotes": "1,652,832",
|
||||
"imdbID": "tt0468569",
|
||||
"Type": "movie",
|
||||
"Response": "True"
|
||||
},
|
||||
{
|
||||
"Title": "Batman Begins",
|
||||
"Year": "2005",
|
||||
"Rated": "PG-13",
|
||||
"Released": "15 Jun 2005",
|
||||
"Runtime": "140 min",
|
||||
"Genre": "Action, Adventure",
|
||||
"Director": "Christopher Nolan",
|
||||
"Writer": "Bob Kane (characters), David S. Goyer (story), Christopher Nolan (screenplay), David S. Goyer (screenplay)",
|
||||
"Actors": "Christian Bale, Michael Caine, Liam Neeson, Katie Holmes",
|
||||
"Plot": "After training with his mentor, Batman begins his fight to free crime-ridden Gotham City from the corruption that Scarecrow and the League of Shadows have cast upon it.",
|
||||
"Language": "English, Urdu, Mandarin",
|
||||
"Country": "USA, UK",
|
||||
"Awards": "Nominated for 1 Oscar. Another 15 wins & 66 nominations.",
|
||||
"Poster": "http://ia.media-imdb.com/images/M/MV5BNTM3OTc0MzM2OV5BMl5BanBnXkFtZTYwNzUwMTI3._V1_SX300.jpg",
|
||||
"Metascore": "70",
|
||||
"imdbRating": "8.3",
|
||||
"imdbVotes": "972,584",
|
||||
"imdbID": "tt0372784",
|
||||
"Type": "movie",
|
||||
"Response": "True"
|
||||
},
|
||||
{
|
||||
"Title": "Avatar",
|
||||
"Year": "2009",
|
||||
"Rated": "PG-13",
|
||||
"Released": "18 Dec 2009",
|
||||
"Runtime": "162 min",
|
||||
"Genre": "Action, Adventure, Fantasy",
|
||||
"Director": "James Cameron",
|
||||
"Writer": "James Cameron",
|
||||
"Actors": "Sam Worthington, Zoe Saldana, Sigourney Weaver, Stephen Lang",
|
||||
"Plot": "A paraplegic marine dispatched to the moon Pandora on a unique mission becomes torn between following his orders and protecting the world he feels is his home.",
|
||||
"Language": "English, Spanish",
|
||||
"Country": "USA, UK",
|
||||
"Awards": "Won 3 Oscars. Another 80 wins & 121 nominations.",
|
||||
"Poster": "http://ia.media-imdb.com/images/M/MV5BMTYwOTEwNjAzMl5BMl5BanBnXkFtZTcwODc5MTUwMw@@._V1_SX300.jpg",
|
||||
"Metascore": "83",
|
||||
"imdbRating": "7.9",
|
||||
"imdbVotes": "876,575",
|
||||
"imdbID": "tt0499549",
|
||||
"Type": "movie",
|
||||
"Response": "True"
|
||||
}
|
||||
];
|
||||
|
||||
const ratings = watchList.map(function(movie) {
|
||||
return {
|
||||
title: movie["Title"],
|
||||
rating: movie["imdbRating"]
|
||||
}
|
||||
});
|
||||
```
|
||||
@@ -0,0 +1,345 @@
|
||||
---
|
||||
id: 587d7da9367417b2b2512b68
|
||||
title: Verwende die Methode reduce, um Daten zu analysieren
|
||||
challengeType: 1
|
||||
forumTopicId: 301313
|
||||
dashedName: use-the-reduce-method-to-analyze-data
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
`Array.prototype.reduce()`, oder einfach `reduce()`, ist die allgemeinste aller Array-Operationen in JavaScript. Du kannst fast jedes Problem bei der Verarbeitung von Arrays mit der Methode `reduce` lösen.
|
||||
|
||||
Die Methode `reduce` ermöglicht allgemeinere Formen der Array-Verarbeitung und es ist möglich zu zeigen, dass sowohl `filter` als auch `map` als spezielle Anwendungen von `reduce` abgeleitet werden können. Die Methode `reduce` iteriert über jedes Element in einem Array und gibt einen einzelnen Wert zurück (z.B. String, Zahl, Objekt, Array). Dies wird über eine Callback-Funktion erreicht, die bei jeder Iteration aufgerufen wird.
|
||||
|
||||
Die Callback-Funktion nimmt vier Argumente entgegen. Das erste Argument ist der Akkumulator, dem der Rückgabewert der Callback-Funktion aus der vorherigen Iteration zugewiesen wird, das zweite ist das aktuell verarbeitete Element, das dritte ist der Index dieses Elements und das vierte ist das Array, auf dem `reduce` aufgerufen wird.
|
||||
|
||||
Neben der Callback-Funktion hat `reduce` einen zusätzlichen Parameter, der einen Anfangswert für den Akkumulator annimmt. Wenn dieser zweite Parameter nicht verwendet wird, wird die erste Iteration übersprungen und der zweiten Iteration wird das erste Element des Arrays als Akkumulator übergeben.
|
||||
|
||||
Unten findest du ein Beispiel, in dem du `reduce` auf das Array `users` anwendest, um die Summe der Altersangaben aller Benutzer zu erhalten. Der Einfachheit halber werden im Beispiel nur das erste und zweite Argument verwendet.
|
||||
|
||||
```js
|
||||
const users = [
|
||||
{ name: 'John', age: 34 },
|
||||
{ name: 'Amy', age: 20 },
|
||||
{ name: 'camperCat', age: 10 }
|
||||
];
|
||||
|
||||
const sumOfAges = users.reduce((sum, user) => sum + user.age, 0);
|
||||
console.log(sumOfAges);
|
||||
```
|
||||
|
||||
Die Konsole würde den Wert `64` ausgeben.
|
||||
|
||||
In einem anderen Beispiel kannst du sehen, wie ein Objekt zurückgegeben werden kann, das die Namen der Benutzer als Eigenschaften und ihr Alter als Werte enthält.
|
||||
|
||||
```js
|
||||
const users = [
|
||||
{ name: 'John', age: 34 },
|
||||
{ name: 'Amy', age: 20 },
|
||||
{ name: 'camperCat', age: 10 }
|
||||
];
|
||||
|
||||
const usersObj = users.reduce((obj, user) => {
|
||||
obj[user.name] = user.age;
|
||||
return obj;
|
||||
}, {});
|
||||
console.log(usersObj);
|
||||
```
|
||||
|
||||
Die Konsole würde den Wert `{ John: 34, Amy: 20, camperCat: 10 }` anzeigen.
|
||||
|
||||
# --instructions--
|
||||
|
||||
Die Variable `watchList` enthält ein Array von Objekten mit Informationen über verschiedene Filme. Verwende `reduce`, um die durchschnittliche IMDB-Bewertung der Filme zu finden, bei denen `Christopher Nolan` Regie geführt hat. Du hast bereits in den vergangenen Aufgaben gelernt, wie man Daten mit `filter` und `map` filtert und zuordnet. Du musst eventuell andere Variablen erstellen und die durchschnittliche Bewertung von der Funktion `getRating` zurückgeben. Beachte, dass die Ratingwerte als Strings im Objekt gespeichert werden und in Zahlen umgewandelt werden müssen, bevor sie in mathematischen Operationen verwendet werden.
|
||||
|
||||
# --hints--
|
||||
|
||||
Die Variable `watchList` sollte sich nicht ändern.
|
||||
|
||||
```js
|
||||
assert(
|
||||
watchList[0].Title === 'Inception' && watchList[4].Director == 'James Cameron'
|
||||
);
|
||||
```
|
||||
|
||||
Dein Code sollte die Methode `reduce` verwenden.
|
||||
|
||||
```js
|
||||
assert(code.match(/\.reduce/g));
|
||||
```
|
||||
|
||||
`getRating(watchList)` sollte gleich 8,675 sein.
|
||||
|
||||
```js
|
||||
assert(getRating(watchList) === 8.675);
|
||||
```
|
||||
|
||||
Dein Code sollte keine `for`-Schleife verwenden.
|
||||
|
||||
```js
|
||||
assert(!code.match(/for\s*?\([\s\S]*?\)/g));
|
||||
```
|
||||
|
||||
Dein Code sollte die richtige Ausgabe zurückgeben, nachdem du das Objekt `watchList` geändert hast.
|
||||
|
||||
```js
|
||||
assert(getRating(watchList.filter((_, i) => i < 1 || i > 2)) === 8.55);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
// The global variable
|
||||
const watchList = [
|
||||
{
|
||||
"Title": "Inception",
|
||||
"Year": "2010",
|
||||
"Rated": "PG-13",
|
||||
"Released": "16 Jul 2010",
|
||||
"Runtime": "148 min",
|
||||
"Genre": "Action, Adventure, Crime",
|
||||
"Director": "Christopher Nolan",
|
||||
"Writer": "Christopher Nolan",
|
||||
"Actors": "Leonardo DiCaprio, Joseph Gordon-Levitt, Elliot Page, Tom Hardy",
|
||||
"Plot": "A thief, who steals corporate secrets through use of dream-sharing technology, is given the inverse task of planting an idea into the mind of a CEO.",
|
||||
"Language": "English, Japanese, French",
|
||||
"Country": "USA, UK",
|
||||
"Awards": "Won 4 Oscars. Another 143 wins & 198 nominations.",
|
||||
"Poster": "http://ia.media-imdb.com/images/M/MV5BMjAxMzY3NjcxNF5BMl5BanBnXkFtZTcwNTI5OTM0Mw@@._V1_SX300.jpg",
|
||||
"Metascore": "74",
|
||||
"imdbRating": "8.8",
|
||||
"imdbVotes": "1,446,708",
|
||||
"imdbID": "tt1375666",
|
||||
"Type": "movie",
|
||||
"Response": "True"
|
||||
},
|
||||
{
|
||||
"Title": "Interstellar",
|
||||
"Year": "2014",
|
||||
"Rated": "PG-13",
|
||||
"Released": "07 Nov 2014",
|
||||
"Runtime": "169 min",
|
||||
"Genre": "Adventure, Drama, Sci-Fi",
|
||||
"Director": "Christopher Nolan",
|
||||
"Writer": "Jonathan Nolan, Christopher Nolan",
|
||||
"Actors": "Ellen Burstyn, Matthew McConaughey, Mackenzie Foy, John Lithgow",
|
||||
"Plot": "A team of explorers travel through a wormhole in space in an attempt to ensure humanity's survival.",
|
||||
"Language": "English",
|
||||
"Country": "USA, UK",
|
||||
"Awards": "Won 1 Oscar. Another 39 wins & 132 nominations.",
|
||||
"Poster": "http://ia.media-imdb.com/images/M/MV5BMjIxNTU4MzY4MF5BMl5BanBnXkFtZTgwMzM4ODI3MjE@._V1_SX300.jpg",
|
||||
"Metascore": "74",
|
||||
"imdbRating": "8.6",
|
||||
"imdbVotes": "910,366",
|
||||
"imdbID": "tt0816692",
|
||||
"Type": "movie",
|
||||
"Response": "True"
|
||||
},
|
||||
{
|
||||
"Title": "The Dark Knight",
|
||||
"Year": "2008",
|
||||
"Rated": "PG-13",
|
||||
"Released": "18 Jul 2008",
|
||||
"Runtime": "152 min",
|
||||
"Genre": "Action, Adventure, Crime",
|
||||
"Director": "Christopher Nolan",
|
||||
"Writer": "Jonathan Nolan (screenplay), Christopher Nolan (screenplay), Christopher Nolan (story), David S. Goyer (story), Bob Kane (characters)",
|
||||
"Actors": "Christian Bale, Heath Ledger, Aaron Eckhart, Michael Caine",
|
||||
"Plot": "When the menace known as the Joker wreaks havoc and chaos on the people of Gotham, the caped crusader must come to terms with one of the greatest psychological tests of his ability to fight injustice.",
|
||||
"Language": "English, Mandarin",
|
||||
"Country": "USA, UK",
|
||||
"Awards": "Won 2 Oscars. Another 146 wins & 142 nominations.",
|
||||
"Poster": "http://ia.media-imdb.com/images/M/MV5BMTMxNTMwODM0NF5BMl5BanBnXkFtZTcwODAyMTk2Mw@@._V1_SX300.jpg",
|
||||
"Metascore": "82",
|
||||
"imdbRating": "9.0",
|
||||
"imdbVotes": "1,652,832",
|
||||
"imdbID": "tt0468569",
|
||||
"Type": "movie",
|
||||
"Response": "True"
|
||||
},
|
||||
{
|
||||
"Title": "Batman Begins",
|
||||
"Year": "2005",
|
||||
"Rated": "PG-13",
|
||||
"Released": "15 Jun 2005",
|
||||
"Runtime": "140 min",
|
||||
"Genre": "Action, Adventure",
|
||||
"Director": "Christopher Nolan",
|
||||
"Writer": "Bob Kane (characters), David S. Goyer (story), Christopher Nolan (screenplay), David S. Goyer (screenplay)",
|
||||
"Actors": "Christian Bale, Michael Caine, Liam Neeson, Katie Holmes",
|
||||
"Plot": "After training with his mentor, Batman begins his fight to free crime-ridden Gotham City from the corruption that Scarecrow and the League of Shadows have cast upon it.",
|
||||
"Language": "English, Urdu, Mandarin",
|
||||
"Country": "USA, UK",
|
||||
"Awards": "Nominated for 1 Oscar. Another 15 wins & 66 nominations.",
|
||||
"Poster": "http://ia.media-imdb.com/images/M/MV5BNTM3OTc0MzM2OV5BMl5BanBnXkFtZTYwNzUwMTI3._V1_SX300.jpg",
|
||||
"Metascore": "70",
|
||||
"imdbRating": "8.3",
|
||||
"imdbVotes": "972,584",
|
||||
"imdbID": "tt0372784",
|
||||
"Type": "movie",
|
||||
"Response": "True"
|
||||
},
|
||||
{
|
||||
"Title": "Avatar",
|
||||
"Year": "2009",
|
||||
"Rated": "PG-13",
|
||||
"Released": "18 Dec 2009",
|
||||
"Runtime": "162 min",
|
||||
"Genre": "Action, Adventure, Fantasy",
|
||||
"Director": "James Cameron",
|
||||
"Writer": "James Cameron",
|
||||
"Actors": "Sam Worthington, Zoe Saldana, Sigourney Weaver, Stephen Lang",
|
||||
"Plot": "A paraplegic marine dispatched to the moon Pandora on a unique mission becomes torn between following his orders and protecting the world he feels is his home.",
|
||||
"Language": "English, Spanish",
|
||||
"Country": "USA, UK",
|
||||
"Awards": "Won 3 Oscars. Another 80 wins & 121 nominations.",
|
||||
"Poster": "http://ia.media-imdb.com/images/M/MV5BMTYwOTEwNjAzMl5BMl5BanBnXkFtZTcwODc5MTUwMw@@._V1_SX300.jpg",
|
||||
"Metascore": "83",
|
||||
"imdbRating": "7.9",
|
||||
"imdbVotes": "876,575",
|
||||
"imdbID": "tt0499549",
|
||||
"Type": "movie",
|
||||
"Response": "True"
|
||||
}
|
||||
];
|
||||
|
||||
function getRating(watchList) {
|
||||
// Only change code below this line
|
||||
let averageRating;
|
||||
|
||||
|
||||
// Only change code above this line
|
||||
return averageRating;
|
||||
}
|
||||
|
||||
console.log(getRating(watchList));
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
const watchList = [
|
||||
{
|
||||
"Title": "Inception",
|
||||
"Year": "2010",
|
||||
"Rated": "PG-13",
|
||||
"Released": "16 Jul 2010",
|
||||
"Runtime": "148 min",
|
||||
"Genre": "Action, Adventure, Crime",
|
||||
"Director": "Christopher Nolan",
|
||||
"Writer": "Christopher Nolan",
|
||||
"Actors": "Leonardo DiCaprio, Joseph Gordon-Levitt, Elliot Page, Tom Hardy",
|
||||
"Plot": "A thief, who steals corporate secrets through use of dream-sharing technology, is given the inverse task of planting an idea into the mind of a CEO.",
|
||||
"Language": "English, Japanese, French",
|
||||
"Country": "USA, UK",
|
||||
"Awards": "Won 4 Oscars. Another 143 wins & 198 nominations.",
|
||||
"Poster": "http://ia.media-imdb.com/images/M/MV5BMjAxMzY3NjcxNF5BMl5BanBnXkFtZTcwNTI5OTM0Mw@@._V1_SX300.jpg",
|
||||
"Metascore": "74",
|
||||
"imdbRating": "8.8",
|
||||
"imdbVotes": "1,446,708",
|
||||
"imdbID": "tt1375666",
|
||||
"Type": "movie",
|
||||
"Response": "True"
|
||||
},
|
||||
{
|
||||
"Title": "Interstellar",
|
||||
"Year": "2014",
|
||||
"Rated": "PG-13",
|
||||
"Released": "07 Nov 2014",
|
||||
"Runtime": "169 min",
|
||||
"Genre": "Adventure, Drama, Sci-Fi",
|
||||
"Director": "Christopher Nolan",
|
||||
"Writer": "Jonathan Nolan, Christopher Nolan",
|
||||
"Actors": "Ellen Burstyn, Matthew McConaughey, Mackenzie Foy, John Lithgow",
|
||||
"Plot": "A team of explorers travel through a wormhole in space in an attempt to ensure humanity's survival.",
|
||||
"Language": "English",
|
||||
"Country": "USA, UK",
|
||||
"Awards": "Won 1 Oscar. Another 39 wins & 132 nominations.",
|
||||
"Poster": "http://ia.media-imdb.com/images/M/MV5BMjIxNTU4MzY4MF5BMl5BanBnXkFtZTgwMzM4ODI3MjE@._V1_SX300.jpg",
|
||||
"Metascore": "74",
|
||||
"imdbRating": "8.6",
|
||||
"imdbVotes": "910,366",
|
||||
"imdbID": "tt0816692",
|
||||
"Type": "movie",
|
||||
"Response": "True"
|
||||
},
|
||||
{
|
||||
"Title": "The Dark Knight",
|
||||
"Year": "2008",
|
||||
"Rated": "PG-13",
|
||||
"Released": "18 Jul 2008",
|
||||
"Runtime": "152 min",
|
||||
"Genre": "Action, Adventure, Crime",
|
||||
"Director": "Christopher Nolan",
|
||||
"Writer": "Jonathan Nolan (screenplay), Christopher Nolan (screenplay), Christopher Nolan (story), David S. Goyer (story), Bob Kane (characters)",
|
||||
"Actors": "Christian Bale, Heath Ledger, Aaron Eckhart, Michael Caine",
|
||||
"Plot": "When the menace known as the Joker wreaks havoc and chaos on the people of Gotham, the caped crusader must come to terms with one of the greatest psychological tests of his ability to fight injustice.",
|
||||
"Language": "English, Mandarin",
|
||||
"Country": "USA, UK",
|
||||
"Awards": "Won 2 Oscars. Another 146 wins & 142 nominations.",
|
||||
"Poster": "http://ia.media-imdb.com/images/M/MV5BMTMxNTMwODM0NF5BMl5BanBnXkFtZTcwODAyMTk2Mw@@._V1_SX300.jpg",
|
||||
"Metascore": "82",
|
||||
"imdbRating": "9.0",
|
||||
"imdbVotes": "1,652,832",
|
||||
"imdbID": "tt0468569",
|
||||
"Type": "movie",
|
||||
"Response": "True"
|
||||
},
|
||||
{
|
||||
"Title": "Batman Begins",
|
||||
"Year": "2005",
|
||||
"Rated": "PG-13",
|
||||
"Released": "15 Jun 2005",
|
||||
"Runtime": "140 min",
|
||||
"Genre": "Action, Adventure",
|
||||
"Director": "Christopher Nolan",
|
||||
"Writer": "Bob Kane (characters), David S. Goyer (story), Christopher Nolan (screenplay), David S. Goyer (screenplay)",
|
||||
"Actors": "Christian Bale, Michael Caine, Liam Neeson, Katie Holmes",
|
||||
"Plot": "After training with his mentor, Batman begins his fight to free crime-ridden Gotham City from the corruption that Scarecrow and the League of Shadows have cast upon it.",
|
||||
"Language": "English, Urdu, Mandarin",
|
||||
"Country": "USA, UK",
|
||||
"Awards": "Nominated for 1 Oscar. Another 15 wins & 66 nominations.",
|
||||
"Poster": "http://ia.media-imdb.com/images/M/MV5BNTM3OTc0MzM2OV5BMl5BanBnXkFtZTYwNzUwMTI3._V1_SX300.jpg",
|
||||
"Metascore": "70",
|
||||
"imdbRating": "8.3",
|
||||
"imdbVotes": "972,584",
|
||||
"imdbID": "tt0372784",
|
||||
"Type": "movie",
|
||||
"Response": "True"
|
||||
},
|
||||
{
|
||||
"Title": "Avatar",
|
||||
"Year": "2009",
|
||||
"Rated": "PG-13",
|
||||
"Released": "18 Dec 2009",
|
||||
"Runtime": "162 min",
|
||||
"Genre": "Action, Adventure, Fantasy",
|
||||
"Director": "James Cameron",
|
||||
"Writer": "James Cameron",
|
||||
"Actors": "Sam Worthington, Zoe Saldana, Sigourney Weaver, Stephen Lang",
|
||||
"Plot": "A paraplegic marine dispatched to the moon Pandora on a unique mission becomes torn between following his orders and protecting the world he feels is his home.",
|
||||
"Language": "English, Spanish",
|
||||
"Country": "USA, UK",
|
||||
"Awards": "Won 3 Oscars. Another 80 wins & 121 nominations.",
|
||||
"Poster": "http://ia.media-imdb.com/images/M/MV5BMTYwOTEwNjAzMl5BMl5BanBnXkFtZTcwODc5MTUwMw@@._V1_SX300.jpg",
|
||||
"Metascore": "83",
|
||||
"imdbRating": "7.9",
|
||||
"imdbVotes": "876,575",
|
||||
"imdbID": "tt0499549",
|
||||
"Type": "movie",
|
||||
"Response": "True"
|
||||
}
|
||||
];
|
||||
|
||||
function getRating(watchList) {
|
||||
let averageRating;
|
||||
const rating = watchList
|
||||
.filter(obj => obj.Director === "Christopher Nolan")
|
||||
.map(obj => Number(obj.imdbRating));
|
||||
averageRating = rating.reduce((accum, curr) => accum + curr)/rating.length;
|
||||
return averageRating;
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,76 @@
|
||||
---
|
||||
id: 587d7dab367417b2b2512b6f
|
||||
title: Verwende die Methode some, um zu prüfen, ob ein Element in einem Array ein Kriterium erfüllt
|
||||
challengeType: 1
|
||||
forumTopicId: 301314
|
||||
dashedName: use-the-some-method-to-check-that-any-elements-in-an-array-meet-a-criteria
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Die Methode `some` arbeitet mit Arrays, um zu prüfen, ob *ein* Element einen bestimmten Test besteht. Sie gibt einen booleschen Wert zurück - `true`, wenn einer der Werte die Kriterien erfüllt, `false`, wenn nicht.
|
||||
|
||||
Der folgende Code würde zum Beispiel prüfen, ob ein Element im Array `numbers` kleiner als 10 ist:
|
||||
|
||||
```js
|
||||
const numbers = [10, 50, 8, 220, 110, 11];
|
||||
|
||||
numbers.some(function(currentValue) {
|
||||
return currentValue < 10;
|
||||
});
|
||||
```
|
||||
|
||||
Die Methode `some` würde `true` zurückgeben.
|
||||
|
||||
# --instructions--
|
||||
|
||||
Verwende die Methode `some` innerhalb der Funktion `checkPositive`, um zu prüfen, ob ein Element in `arr` positiv ist. Die Funktion sollte einen booleschen Wert zurückgeben.
|
||||
|
||||
# --hints--
|
||||
|
||||
Dein Code sollte die Methode `some` verwenden.
|
||||
|
||||
```js
|
||||
assert(code.match(/\.some/g));
|
||||
```
|
||||
|
||||
`checkPositive([1, 2, 3, -4, 5])` sollte `true` zurückgeben.
|
||||
|
||||
```js
|
||||
assert(checkPositive([1, 2, 3, -4, 5]));
|
||||
```
|
||||
|
||||
`checkPositive([1, 2, 3, 4, 5])` sollte `true` zurückgeben.
|
||||
|
||||
```js
|
||||
assert(checkPositive([1, 2, 3, 4, 5]));
|
||||
```
|
||||
|
||||
`checkPositive([-1, -2, -3, -4, -5])` sollte `false` zurückgeben.
|
||||
|
||||
```js
|
||||
assert(!checkPositive([-1, -2, -3, -4, -5]));
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```js
|
||||
function checkPositive(arr) {
|
||||
// Only change code below this line
|
||||
|
||||
|
||||
// Only change code above this line
|
||||
}
|
||||
|
||||
checkPositive([1, 2, 3, -4, 5]);
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
function checkPositive(arr) {
|
||||
return arr.some(elem => elem > 0);
|
||||
}
|
||||
```
|
||||
Reference in New Issue
Block a user