Skip to content

Commit b366028

Browse files
committed
Merge branch 'master' of C:/Users/osvaldo/Documents/GitHub/copy/en.javascript.info into fix-data-types
2 parents 10ebca8 + 2e52c9c commit b366028

File tree

11 files changed

+558
-0
lines changed

11 files changed

+558
-0
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
function unique(arr) {
2+
return Array.from(new Set(arr));
3+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
describe("unique", function() {
2+
it("removes non-unique elements", function() {
3+
let strings = ["Hare", "Krishna", "Hare", "Krishna",
4+
"Krishna", "Krishna", "Hare", "Hare", ":-O"
5+
];
6+
7+
assert.deepEqual(unique(strings), ["Hare", "Krishna", ":-O"]);
8+
});
9+
10+
it("does not change the source array", function() {
11+
let strings = ["Krishna", "Krishna", "Hare", "Hare"];
12+
unique(strings);
13+
assert.deepEqual(strings, ["Krishna", "Krishna", "Hare", "Hare"]);
14+
});
15+
});

1-js/05-data-types/07-map-set/01-array-unique-map/solution.md

Whitespace-only changes.
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
importance: 5
2+
3+
---
4+
5+
# Filter unique array members
6+
7+
Let `arr` be an array.
8+
9+
Create a function `unique(arr)` that should return an array with unique items of `arr`.
10+
11+
For instance:
12+
13+
```js
14+
function unique(arr) {
15+
/* your code */
16+
}
17+
18+
let values = ["Hare", "Krishna", "Hare", "Krishna",
19+
"Krishna", "Krishna", "Hare", "Hare", ":-O"
20+
];
21+
22+
alert( unique(values) ); // Hare, Krishna, :-O
23+
```
24+
25+
P.S. Here strings are used, but can be values of any type.
26+
27+
P.P.S. Use `Set` to store unique values.
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
2+
function aclean(arr) {
3+
let map = new Map();
4+
5+
for(let word of arr) {
6+
let sorted = word.toLowerCase().split("").sort().join("");
7+
map.set(sorted, word);
8+
}
9+
10+
return Array.from(map.values());
11+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
function intersection(arr1, arr2) {
2+
return arr1.filter(item => arr2.includes(item));
3+
}
4+
5+
describe("aclean", function() {
6+
7+
it("returns exactly 1 word from each anagram set", function() {
8+
let arr = ["nap", "teachers", "cheaters", "PAN", "ear", "era", "hectares"];
9+
10+
let result = aclean(arr);
11+
assert.equal(result.length, 3);
12+
13+
assert.equal(intersection(result, ["nap", "PAN"]).length, 1);
14+
assert.equal(intersection(result, ["teachers", "cheaters", "hectares"]).length, 1);
15+
assert.equal(intersection(result, ["ear", "era"]).length, 1);
16+
17+
});
18+
19+
it("is case-insensitive", function() {
20+
let arr = ["era", "EAR"];
21+
assert.equal(aclean(arr).length, 1);
22+
});
23+
24+
});
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
To find all anagrams, let's split every word to letters and sort them. When letter-sorted, all anagrams are same.
2+
3+
For instance:
4+
5+
```
6+
nap, pan -> anp
7+
ear, era, are -> aer
8+
cheaters, hectares, teachers -> aceehrst
9+
...
10+
```
11+
12+
We'll use the letter-sorted variants as map keys to store only one value per each key:
13+
14+
```js run
15+
function aclean(arr) {
16+
let map = new Map();
17+
18+
for (let word of arr) {
19+
// split the word by letters, sort them and join back
20+
*!*
21+
let sorted = word.toLowerCase().split('').sort().join(''); // (*)
22+
*/!*
23+
map.set(sorted, word);
24+
}
25+
26+
return Array.from(map.values());
27+
}
28+
29+
let arr = ["nap", "teachers", "cheaters", "PAN", "ear", "era", "hectares"];
30+
31+
alert( aclean(arr) );
32+
```
33+
34+
Letter-sorting is done by the chain of calls in the line `(*)`.
35+
36+
For convenience let's split it into multiple lines:
37+
38+
```js
39+
let sorted = word // PAN
40+
.toLowerCase() // pan
41+
.split('') // ['p','a','n']
42+
.sort() // ['a','n','p']
43+
.join(''); // anp
44+
```
45+
46+
Two different words `'PAN'` and `'nap'` receive the same letter-sorted form `'anp'`.
47+
48+
The next line put the word into the map:
49+
50+
```js
51+
map.set(sorted, word);
52+
```
53+
54+
If we ever meet a word the same letter-sorted form again, then it would overwrite the previous value with the same key in the map. So we'll always have at maximum one word per letter-form.
55+
56+
At the end `Array.from(map.values())` takes an iterable over map values (we don't need keys in the result) and returns an array of them.
57+
58+
Here we could also use a plain object instead of the `Map`, because keys are strings.
59+
60+
That's how the solution can look:
61+
62+
```js run demo
63+
function aclean(arr) {
64+
let obj = {};
65+
66+
for (let i = 0; i < arr.length; i++) {
67+
let sorted = arr[i].toLowerCase().split("").sort().join("");
68+
obj[sorted] = arr[i];
69+
}
70+
71+
return Object.values(obj);
72+
}
73+
74+
let arr = ["nap", "teachers", "cheaters", "PAN", "ear", "era", "hectares"];
75+
76+
alert( aclean(arr) );
77+
```
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
importance: 4
2+
3+
---
4+
5+
# Filter anagrams
6+
7+
[Anagrams](https://en.wikipedia.org/wiki/Anagram) are words that have the same number of same letters, but in different order.
8+
9+
For instance:
10+
11+
```
12+
nap - pan
13+
ear - are - era
14+
cheaters - hectares - teachers
15+
```
16+
17+
Write a function `aclean(arr)` that returns an array cleaned from anagrams.
18+
19+
For instance:
20+
21+
```js
22+
let arr = ["nap", "teachers", "cheaters", "PAN", "ear", "era", "hectares"];
23+
24+
alert( aclean(arr) ); // "nap,teachers,ear" or "PAN,cheaters,era"
25+
```
26+
27+
From every anagram group should remain only one word, no matter which one.
28+
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
2+
That's because `map.keys()` returns an iterable, but not an array.
3+
4+
We can convert it into an array using `Array.from`:
5+
6+
7+
```js run
8+
let map = new Map();
9+
10+
map.set("name", "John");
11+
12+
*!*
13+
let keys = Array.from(map.keys());
14+
*/!*
15+
16+
keys.push("more");
17+
18+
alert(keys); // name, more
19+
```
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
importance: 5
2+
3+
---
4+
5+
# Iterable keys
6+
7+
We'd like to get an array of `map.keys()` in a variable and then do apply array-specific methods to it, e.g. `.push`.
8+
9+
But that doesn't work:
10+
11+
```js run
12+
let map = new Map();
13+
14+
map.set("name", "John");
15+
16+
let keys = map.keys();
17+
18+
*!*
19+
// Error: keys.push is not a function
20+
keys.push("more");
21+
*/!*
22+
```
23+
24+
Why? How can we fix the code to make `keys.push` work?

0 commit comments

Comments
 (0)