From b63e9f7ab474fb5650a2d7425028b2f84b10075d Mon Sep 17 00:00:00 2001 From: Vasyl Onopriienko Date: Thu, 22 Jul 2021 12:46:54 +0300 Subject: [PATCH 01/12] Map and Set translation --- .../01-array-unique-map/_js.view/test.js | 4 +- .../07-map-set/01-array-unique-map/task.md | 14 +- .../02-filter-anagrams/_js.view/test.js | 6 +- .../07-map-set/02-filter-anagrams/solution.md | 25 +- .../07-map-set/02-filter-anagrams/task.md | 12 +- .../07-map-set/03-iterable-keys/solution.md | 4 +- .../07-map-set/03-iterable-keys/task.md | 10 +- 1-js/05-data-types/07-map-set/article.md | 240 +++++++++--------- 8 files changed, 157 insertions(+), 158 deletions(-) diff --git a/1-js/05-data-types/07-map-set/01-array-unique-map/_js.view/test.js b/1-js/05-data-types/07-map-set/01-array-unique-map/_js.view/test.js index cfc7b1fc3..dd147d151 100644 --- a/1-js/05-data-types/07-map-set/01-array-unique-map/_js.view/test.js +++ b/1-js/05-data-types/07-map-set/01-array-unique-map/_js.view/test.js @@ -1,5 +1,5 @@ describe("unique", function() { - it("removes non-unique elements", function() { + it("видалити не унікальні елементи", function() { let strings = ["Hare", "Krishna", "Hare", "Krishna", "Krishna", "Krishna", "Hare", "Hare", ":-O" ]; @@ -7,7 +7,7 @@ describe("unique", function() { assert.deepEqual(unique(strings), ["Hare", "Krishna", ":-O"]); }); - it("does not change the source array", function() { + it("не змінювати вихідний масив", function() { let strings = ["Krishna", "Krishna", "Hare", "Hare"]; unique(strings); assert.deepEqual(strings, ["Krishna", "Krishna", "Hare", "Hare"]); diff --git a/1-js/05-data-types/07-map-set/01-array-unique-map/task.md b/1-js/05-data-types/07-map-set/01-array-unique-map/task.md index d68030032..a58cb27f9 100644 --- a/1-js/05-data-types/07-map-set/01-array-unique-map/task.md +++ b/1-js/05-data-types/07-map-set/01-array-unique-map/task.md @@ -2,17 +2,17 @@ importance: 5 --- -# Filter unique array members +# Фільтрувати унікальні елементи масиву -Let `arr` be an array. +Нехай `arr` - це масив. -Create a function `unique(arr)` that should return an array with unique items of `arr`. +Потрібно створити функцію `unique(arr)`, яка повинна повертати масив унікальних елементів `arr`. -For instance: +Наприклад: ```js function unique(arr) { - /* your code */ + /* Твій код */ } let values = ["Hare", "Krishna", "Hare", "Krishna", @@ -22,6 +22,6 @@ let values = ["Hare", "Krishna", "Hare", "Krishna", alert( unique(values) ); // Hare, Krishna, :-O ``` -P.S. Here strings are used, but can be values of any type. +P.S. В прикладі ми використали рядки, але можуть бути значення будь якого типу. -P.P.S. Use `Set` to store unique values. +P.P.S. Використайте `Set` для формування множини унікальних значень. diff --git a/1-js/05-data-types/07-map-set/02-filter-anagrams/_js.view/test.js b/1-js/05-data-types/07-map-set/02-filter-anagrams/_js.view/test.js index 75acb36b7..74accad4b 100644 --- a/1-js/05-data-types/07-map-set/02-filter-anagrams/_js.view/test.js +++ b/1-js/05-data-types/07-map-set/02-filter-anagrams/_js.view/test.js @@ -2,9 +2,9 @@ function intersection(arr1, arr2) { return arr1.filter(item => arr2.includes(item)); } -describe("aclean", function() { +describe("aclean", function () { - it("returns exactly 1 word from each anagram set", function() { + it("повертає тільки 1 слово для кожного набору анаграм", function () { let arr = ["nap", "teachers", "cheaters", "PAN", "ear", "era", "hectares"]; let result = aclean(arr); @@ -16,7 +16,7 @@ describe("aclean", function() { }); - it("is case-insensitive", function() { + it("не враховує регістр", function () { let arr = ["era", "EAR"]; assert.equal(aclean(arr).length, 1); }); diff --git a/1-js/05-data-types/07-map-set/02-filter-anagrams/solution.md b/1-js/05-data-types/07-map-set/02-filter-anagrams/solution.md index 160675185..af831bfd7 100644 --- a/1-js/05-data-types/07-map-set/02-filter-anagrams/solution.md +++ b/1-js/05-data-types/07-map-set/02-filter-anagrams/solution.md @@ -1,6 +1,5 @@ -To find all anagrams, let's split every word to letters and sort them. When letter-sorted, all anagrams are same. - -For instance: +Щоб знайти всі анаграми, давайте розіб'ємо кожне слово на літери і відсортуємо їх, а потім об'єднаємо масив знову в рядок. Після цього всі анаграми будуть однакові. +Наприклад: ``` nap, pan -> anp @@ -9,14 +8,14 @@ cheaters, hectares, teachers -> aceehrst ... ``` -We'll use the letter-sorted variants as map keys to store only one value per each key: +Ми будемо використовувати відсортовані рядки як ключі в колекції Map, для того щоб зіставити кожному ключу тільки одне значення: ```js run function aclean(arr) { let map = new Map(); for (let word of arr) { - // split the word by letters, sort them and join back + // розділіть слово на літери, відсортуйте їх та знову з'єднайте *!* let sorted = word.toLowerCase().split('').sort().join(''); // (*) */!* @@ -31,9 +30,9 @@ let arr = ["nap", "teachers", "cheaters", "PAN", "ear", "era", "hectares"]; alert( aclean(arr) ); ``` -Letter-sorting is done by the chain of calls in the line `(*)`. +Сортування літер здійснюється ланцюжком викликів одним рядком `(*)`. -For convenience let's split it into multiple lines: +Для зручності давайте розіб'ємо на декілька рядків: ```js let sorted = word // PAN @@ -43,21 +42,21 @@ let sorted = word // PAN .join(''); // anp ``` -Two different words `'PAN'` and `'nap'` receive the same letter-sorted form `'anp'`. +Два різних слова `'PAN'` і `'nap'` приймають ту ж саму форму після сортування букв - `'anp'`. -The next line put the word into the map: +Наступна лінія поміщає слово в об'єкт `Map`: ```js map.set(sorted, word); ``` -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. +Якщо ми коли-небудь ще зустрінемо слово в тій же відсортованої формі, тоді це слово перезапише значення з тим же ключем в об'єкті. Таким чином, декільком словами у нас буде завжди відповідати одна відсортована форма. -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. +Врешті-решт `Array.from(map.values())` приймає значення об'єкту-ітератора 'Map' (в даному випадку нам не потрібні ключі) і повертає їх у вигляді масиву. -Here we could also use a plain object instead of the `Map`, because keys are strings. +Тут ми також можемо використовувати звичайний об'єкт замість `Map`, тому що ключі - це рядки. -That's how the solution can look: +Ось один з варіантів рішень задачі: ```js run demo function aclean(arr) { diff --git a/1-js/05-data-types/07-map-set/02-filter-anagrams/task.md b/1-js/05-data-types/07-map-set/02-filter-anagrams/task.md index 731fd2c25..b467f8fb7 100644 --- a/1-js/05-data-types/07-map-set/02-filter-anagrams/task.md +++ b/1-js/05-data-types/07-map-set/02-filter-anagrams/task.md @@ -2,11 +2,11 @@ importance: 4 --- -# Filter anagrams +# Відфілтруйте анаграми -[Anagrams](https://en.wikipedia.org/wiki/Anagram) are words that have the same number of same letters, but in different order. +[Анаграми](https://en.wikipedia.org/wiki/Anagram) -- це слова, у яких ті ж букви в тій же кількості, але вони розташовуються в іншому порядку. -For instance: +Наприклад: ``` nap - pan @@ -14,9 +14,9 @@ ear - are - era cheaters - hectares - teachers ``` -Write a function `aclean(arr)` that returns an array cleaned from anagrams. +Напишіть функцію `aclean(arr)`, яка повертає масив без анаграм. -For instance: +Наприклад: ```js let arr = ["nap", "teachers", "cheaters", "PAN", "ear", "era", "hectares"]; @@ -24,5 +24,5 @@ let arr = ["nap", "teachers", "cheaters", "PAN", "ear", "era", "hectares"]; alert( aclean(arr) ); // "nap,teachers,ear" or "PAN,cheaters,era" ``` -From every anagram group should remain only one word, no matter which one. +З кожної групи анаграм має залишитися тільки одне слово, не має значення яке. diff --git a/1-js/05-data-types/07-map-set/03-iterable-keys/solution.md b/1-js/05-data-types/07-map-set/03-iterable-keys/solution.md index 7310d1d36..33730a6fa 100644 --- a/1-js/05-data-types/07-map-set/03-iterable-keys/solution.md +++ b/1-js/05-data-types/07-map-set/03-iterable-keys/solution.md @@ -1,7 +1,7 @@ -That's because `map.keys()` returns an iterable, but not an array. +Ми отримали помилку тому, що `map.keys()` повертає об'єкт-ітератор, а не масив. -We can convert it into an array using `Array.from`: +Ми можемо конвертувати його використовуючи `Array.from`: ```js run diff --git a/1-js/05-data-types/07-map-set/03-iterable-keys/task.md b/1-js/05-data-types/07-map-set/03-iterable-keys/task.md index 81507647f..153dce513 100644 --- a/1-js/05-data-types/07-map-set/03-iterable-keys/task.md +++ b/1-js/05-data-types/07-map-set/03-iterable-keys/task.md @@ -2,11 +2,11 @@ importance: 5 --- -# Iterable keys +# Перебираємо ключі -We'd like to get an array of `map.keys()` in a variable and then apply array-specific methods to it, e.g. `.push`. +Ми хотіли б отримати масив ключів 'map.keys()' в змінну і далі працювати з ними, наприклад, застосувати метод `.push`. -But that doesn't work: +Але так не спрацює: ```js run let map = new Map(); @@ -16,9 +16,9 @@ map.set("name", "John"); let keys = map.keys(); *!* -// Error: keys.push is not a function +// Помилка: keys.push -- це не функція keys.push("more"); */!* ``` -Why? How can we fix the code to make `keys.push` work? +Чому? Що потрібно виправити в коді, щоб `keys.push` працював? diff --git a/1-js/05-data-types/07-map-set/article.md b/1-js/05-data-types/07-map-set/article.md index bd6cad562..44a1655e7 100644 --- a/1-js/05-data-types/07-map-set/article.md +++ b/1-js/05-data-types/07-map-set/article.md @@ -1,97 +1,97 @@ -# Map and Set +# Map і Set -Till now, we've learned about the following complex data structures: +Зараз ми знаємо про наступні складні структури даних: -- Objects are used for storing keyed collections. -- Arrays are used for storing ordered collections. +- Об'єкти для зберігання іменованих колекцій. +- Масиви для зберігання впорядкованих колекцій. -But that's not enough for real life. That's why `Map` and `Set` also exist. +Але цього не завжди достатньо в реальному житті. Ось чому існують `Map` і `Set`. ## Map -[Map](mdn:js/Map) is a collection of keyed data items, just like an `Object`. But the main difference is that `Map` allows keys of any type. +[Map](mdn:js/Map) це колекція ключ/значення, як і `Object`. Але основна відмінність полягає в тому, що `Map` дозволяє мати ключі будь-якого типу. -Methods and properties are: +Методи і властивості: -- `new Map()` -- creates the map. -- `map.set(key, value)` -- stores the value by the key. -- `map.get(key)` -- returns the value by the key, `undefined` if `key` doesn't exist in map. -- `map.has(key)` -- returns `true` if the `key` exists, `false` otherwise. -- `map.delete(key)` -- removes the value by the key. -- `map.clear()` -- removes everything from the map. -- `map.size` -- returns the current element count. +- `new Map()` -- створює колекцію. +- `map.set(key, value)` -- зберігає значення `value` за ключем `key`. +- `map.get(key)` -- повертає значення за ключем, повертає `undefined` якщо `key` не існує в колекції. +- `map.has(key)` -- повертає `true` якщо `key` існує, інакше `false`. +- `map.delete(key)` -- видаляє елемент по ключу. +- `map.clear()` -- видаляє всі елементи колекції. +- `map.size` -- повертає поточну кількість елементів. -For instance: +Наприклад: ```js run let map = new Map(); -map.set('1', 'str1'); // a string key -map.set(1, 'num1'); // a numeric key -map.set(true, 'bool1'); // a boolean key +map.set('1', 'str1'); // рядок в якості ключа +map.set(1, 'num1'); // цифра як ключ +map.set(true, 'bool1'); // булеве значення як ключ -// remember the regular Object? it would convert keys to string -// Map keeps the type, so these two are different: +// пам'ятайте, звичайний об'єкт `Object` призводить ключі до рядків? +// Map зберігає тип ключів, так що в цьому випадку ми отримаємо 2 різних значення: alert( map.get(1) ); // 'num1' alert( map.get('1') ); // 'str1' alert( map.size ); // 3 ``` -As we can see, unlike objects, keys are not converted to strings. Any type of key is possible. +Як ми бачимо, на відміну від об'єктів, ключі не були приведені до рядків. Можна використовувати будь-які типи даних для ключів. -```smart header="`map[key]` isn't the right way to use a `Map`" -Although `map[key]` also works, e.g. we can set `map[key] = 2`, this is treating `map` as a plain JavaScript object, so it implies all corresponding limitations (only string/symbol keys and so on). +```smart header="`map[key]` не є правильним методом використання `Map`" +Хоча `map[key]` також працює, але такий спосіб присвоєння `map[key] = 2` використовує колекцію як звичайний JavaScript об'єкт, тобто накладає відповідні обмеження (тільки типи рядки/символи як ключі і так далі). -So we should use `map` methods: `set`, `get` and so on. +Таким чином ми повинні користуватись `map` методами: `set`, `get` і так далі. ``` -**Map can also use objects as keys.** +**Map також може використовувати об'єкти як ключі.** -For instance: +Наприклад: ```js run let john = { name: "John" }; -// for every user, let's store their visits count +// давайте збережемо кількість відвідувань для кожного користувача let visitsCountMap = new Map(); -// john is the key for the map +// об'єкт john -- це ключ для значення в колекції Map visitsCountMap.set(john, 123); alert( visitsCountMap.get(john) ); // 123 ``` -Using objects as keys is one of the most notable and important `Map` features. The same does not count for `Object`. String as a key in `Object` is fine, but we can't use another `Object` as a key in `Object`. +Використання об'єктів в якості ключів -- це одна з відомих і часто застосовуваних можливостей колекції Map. Ми можемо використати ключі-рядки для об'єкту `Object`, але для ключів-об'єктів -- вже ні. -Let's try: +Спробуємо замінити Map на Object в прикладі вище:: ```js run let john = { name: "John" }; let ben = { name: "Ben" }; -let visitsCountObj = {}; // try to use an object +let visitsCountObj = {}; // використаємо об'єкт -visitsCountObj[ben] = 234; // try to use ben object as the key -visitsCountObj[john] = 123; // try to use john object as the key, ben object will get replaced +visitsCountObj[ben] = 234; // використаємо `ben` об'єкт як ключ +visitsCountObj[john] = 123; // використаємо `john` об'єкт як ключ, `ben` об'єкт буде перезаписаний *!* -// That's what got written! +// Ось як це було записано! alert( visitsCountObj["[object Object]"] ); // 123 */!* ``` -As `visitsCountObj` is an object, it converts all `Object` keys, such as `john` and `ben` above, to same string `"[object Object]"`. Definitely not what we want. +Так як `visitsCountObj` -- це об'єкт, він конвертує всі ключі, такі як `john` і `ben`, до рядку `"[object Object]"`. Це однозначно не той результат, який ми очікуємо. -```smart header="How `Map` compares keys" -To test keys for equivalence, `Map` uses the algorithm [SameValueZero](https://tc39.github.io/ecma262/#sec-samevaluezero). It is roughly the same as strict equality `===`, but the difference is that `NaN` is considered equal to `NaN`. So `NaN` can be used as the key as well. +```smart header="Як об'єкт `Map` порінює ключі" +Щоб порівняти ключі, об'єкт `Map` використовує алгоритм [SameValueZero](https://tc39.github.io/ecma262/#sec-samevaluezero). Це майже таке ж порівняння, що і `===`, з тією лише різницею, що `NaN` вважається рівним `NaN`. Таким чином `NaN` може також бути використаний як ключ. -This algorithm can't be changed or customized. +Цей алгоритм не може бути замінений або модифікований. ``` -````smart header="Chaining" -Every `map.set` call returns the map itself, so we can "chain" the calls: +````smart header="Послідовні виклики" +Кожен виклик `map.set` повертає об'єкт map, таким чином ми можемо об'єднати виклики в ланцюжок: ```js map.set('1', 'str1') @@ -101,15 +101,15 @@ map.set('1', 'str1') ```` -## Iteration over Map +## Перебір Map -For looping over a `map`, there are 3 methods: +Для перебору колекції Map є 3 метода: -- `map.keys()` -- returns an iterable for keys, -- `map.values()` -- returns an iterable for values, -- `map.entries()` -- returns an iterable for entries `[key, value]`, it's used by default in `for..of`. +- `map.keys()` -- повертає об'єкт-ітератор для ключів, +- `map.values()` -- повертає об'єкт-ітератор для значень, +- `map.entries()` -- повертає об'єкт-ітератор зі значеннями виду [ключ, значення], цей варіант використовується за умовчанням в for..of. -For instance: +Наприклад: ```js run let recipeMap = new Map([ @@ -118,41 +118,41 @@ let recipeMap = new Map([ ['onion', 50] ]); -// iterate over keys (vegetables) +// перебираємо ключі (овочі) for (let vegetable of recipeMap.keys()) { alert(vegetable); // cucumber, tomatoes, onion } -// iterate over values (amounts) +// перебираємо значення (числа) for (let amount of recipeMap.values()) { alert(amount); // 500, 350, 50 } -// iterate over [key, value] entries -for (let entry of recipeMap) { // the same as of recipeMap.entries() - alert(entry); // cucumber,500 (and so on) +// перебір елементів в форматі [ключ, значення] +for (let entry of recipeMap) { // те ж саме, що recipeMap.entries() + alert(entry); // cucumber,500 (і так далі) } ``` -```smart header="The insertion order is used" -The iteration goes in the same order as the values were inserted. `Map` preserves this order, unlike a regular `Object`. +```smart header="Використовується порядок вставки" +На відміну від звичайних об'єктів `Object`, в `Map` перебір відбувається в тому ж порядку, в якому відбувалося додавання елементів. ``` -Besides that, `Map` has a built-in `forEach` method, similar to `Array`: +Крім цього, `Map` має вбудований метод `forEach`, схожий з вбудованим методом масивів `Array`: ```js -// runs the function for each (key, value) pair +// виконуємо функцію для кожної пари (ключ, значення) recipeMap.forEach( (value, key, map) => { - alert(`${key}: ${value}`); // cucumber: 500 etc + alert(`${key}: ${value}`); // cucumber: 500 і так далі }); ``` -## Object.entries: Map from Object +## Object.entries: Map з Object -When a `Map` is created, we can pass an array (or another iterable) with key/value pairs for initialization, like this: +При створенні `Map` ми можемо вказати масив (або інший об'єкт-ітератор) з парами ключ-значення для ініціалізації, як тут: ```js run -// array of [key, value] pairs +// масив пар [ключ, значення] let map = new Map([ ['1', 'str1'], [1, 'num1'], @@ -162,9 +162,9 @@ let map = new Map([ alert( map.get('1') ); // str1 ``` -If we have a plain object, and we'd like to create a `Map` from it, then we can use built-in method [Object.entries(obj)](mdn:js/Object/entries) that returns an array of key/value pairs for an object exactly in that format. +Якщо у нас вже є звичайний об'єкт, і ми хотіли б створити `Map` з нього, то допоможе вбудований метод [Object.entries(obj)](mdn:js/Object/entries) який отримує об'єкт і повертає масив пар ключ-значення для нього, як раз в цьому форматі. -So we can create a map from an object like this: +Таким чином ми можемо створити `Map` з об'єкту наступним чином: ```js run let obj = { @@ -179,14 +179,14 @@ let map = new Map(Object.entries(obj)); alert( map.get('name') ); // John ``` -Here, `Object.entries` returns the array of key/value pairs: `[ ["name","John"], ["age", 30] ]`. That's what `Map` needs. +Тут, `Object.entries` повертає масив пар ключ-значення: `[ ["name","John"], ["age", 30] ]`. Це саме те, що потрібно для створення `Map`. -## Object.fromEntries: Object from Map +## Object.fromEntries: Object з Map -We've just seen how to create `Map` from a plain object with `Object.entries(obj)`. +Ми щойно створювали `Map` з простого об'єкту за допомогою `Object.entries(obj)`. -There's `Object.fromEntries` method that does the reverse: given an array of `[key, value]` pairs, it creates an object from them: +Ми можемо використати `Object.fromEntries` метод, який виконає зворотну дію: трансформує отриманий масив пар `[ключ, значення]` в об'єкт. Наприклад: ```js run let prices = Object.fromEntries([ @@ -200,11 +200,11 @@ let prices = Object.fromEntries([ alert(prices.orange); // 2 ``` -We can use `Object.fromEntries` to get a plain object from `Map`. +Ми можемо використати `Object.fromEntries`, щоб отримати звичайний об'єкт з `Map`. -E.g. we store the data in a `Map`, but we need to pass it to a 3rd-party code that expects a plain object. +Наприклад, ми маємо дані в `Map`, але потрібно їх передати в сторонній код, який чекає простий об'єкт. -Here we go: +Ось як це зробити: ```js run let map = new Map(); @@ -213,42 +213,42 @@ map.set('orange', 2); map.set('meat', 4); *!* -let obj = Object.fromEntries(map.entries()); // make a plain object (*) +let obj = Object.fromEntries(map.entries()); // робимо простий об'єкт (*) */!* -// done! +// Готово! // obj = { banana: 1, orange: 2, meat: 4 } alert(obj.orange); // 2 ``` -A call to `map.entries()` returns an iterable of key/value pairs, exactly in the right format for `Object.fromEntries`. +Виклик `map.entries()` повертає масив пар ключ/значення, як раз в потрібному форматі для `Object.fromEntries`. -We could also make line `(*)` shorter: +Ми могли б написати рядок `(*)` ще коротше: ```js -let obj = Object.fromEntries(map); // omit .entries() +let obj = Object.fromEntries(map); // прибрати .entries() ``` -That's the same, because `Object.fromEntries` expects an iterable object as the argument. Not necessarily an array. And the standard iteration for `map` returns same key/value pairs as `map.entries()`. So we get a plain object with same key/values as the `map`. +Це те ж саме, так як `Object.fromEntries` чекає аргументом об'єкт-ітератор, не обов'язково масив. А перебір `map` якраз повертає пари ключ/значення, як і `map.entries()`. Так що в підсумку ми матимемо звичайний об'єкт з тими ж ключами/значеннями, що і в `map`. ## Set -A `Set` is a special type collection - "set of values" (without keys), where each value may occur only once. +Об'єкт `Set` -- це особливий тип колекції: "множина" значень (без ключів), де кожне значення може з'являтися тільки раз. -Its main methods are: +Основні методи: -- `new Set(iterable)` -- creates the set, and if an `iterable` object is provided (usually an array), copies values from it into the set. -- `set.add(value)` -- adds a value, returns the set itself. -- `set.delete(value)` -- removes the value, returns `true` if `value` existed at the moment of the call, otherwise `false`. -- `set.has(value)` -- returns `true` if the value exists in the set, otherwise `false`. -- `set.clear()` -- removes everything from the set. -- `set.size` -- is the elements count. +- `new Set(iterable)` -- створює об'єкт `Set`, якщо аргументом виступає об'єкт-ітератор, тоді значення копіюються в `Set`. +- `set.add(value)` -- додає нове значення до `Set`, повертає об'єкт `Set`. +- `set.delete(value)` -- видаляє значення з `Set`, повертає `true`, якщо `value` наявне в множині значень на момент виклику методу, інакше `false`. +- `set.has(value)` -- повертає `true`, якщо `value` присутнє в множині `Set`, інакше `false`. +- `set.clear()` -- видаляє всі значення множини `Set`. +- `set.size` -- повертає кількість елементів в множині. -The main feature is that repeated calls of `set.add(value)` with the same value don't do anything. That's the reason why each value appears in a `Set` only once. +Родзинкою `Set` є виклики `set.add(value)`, що повторюються з однаковими значеннями `value`. Повторні виклики цього методу не змінюють об'єкт `Set`. Це причина того, що кожне значення з'являється тільки один раз. -For example, we have visitors coming, and we'd like to remember everyone. But repeated visits should not lead to duplicates. A visitor must be "counted" only once. +Наприклад, ми очікуємо гостей, і нам необхідно скласти їх список. Але повторні записи не повинні призводити до дублікатів. Кожен гість повинен з'явитися в списку лише один раз. -`Set` is just the right thing for that: +Множина `Set` -- це саме те, що потрібно для цього: ```js run let set = new Set(); @@ -257,76 +257,76 @@ let john = { name: "John" }; let pete = { name: "Pete" }; let mary = { name: "Mary" }; -// visits, some users come multiple times +// підраховуємо гостей, деякі приходять кілька разів set.add(john); set.add(pete); set.add(mary); set.add(john); set.add(mary); -// set keeps only unique values +// set зберігає тільки 3 унікальних значення alert( set.size ); // 3 for (let user of set) { - alert(user.name); // John (then Pete and Mary) + alert(user.name); // John (тоді Pete і Mary) } ``` -The alternative to `Set` could be an array of users, and the code to check for duplicates on every insertion using [arr.find](mdn:js/Array/find). But the performance would be much worse, because this method walks through the whole array checking every element. `Set` is much better optimized internally for uniqueness checks. +Альтернативою множини `Set``'ї може виступати масив для зберігання гостей і додатковий код для перевірки вже наявного елемента за допомогою [arr.find](mdn:js/Array/find). Але в цьому випадку буде гірша продуктивність, тому що `arr.find` проходить весь масив для перевірки наявності елемента. Множина `Set` краще оптимізована для перевірки унікальності. -## Iteration over Set +## Перебір об'єкта Set -We can loop over a set either with `for..of` or using `forEach`: +Ми можемо перебрати вміст об'єкта 'set' як за допомогою методу 'for..of', так і використовуючи 'forEach': ```js run let set = new Set(["oranges", "apples", "bananas"]); for (let value of set) alert(value); -// the same with forEach: +// те ж саме з forEach: set.forEach((value, valueAgain, set) => { alert(value); }); ``` -Note the funny thing. The callback function passed in `forEach` has 3 arguments: a `value`, then *the same value* `valueAgain`, and then the target object. Indeed, the same value appears in the arguments twice. +Зауважимо забавну річ. Функція в `forEach` у `Set` має 3 аргумента: значення `value`, потім знову *те ж саме значення* `valueAgain`, і тільки потім цільовий об'єкт. Це дійсно так, значення з'являється в списку аргументів двічі. -That's for compatibility with `Map` where the callback passed `forEach` has three arguments. Looks a bit strange, for sure. But may help to replace `Map` with `Set` in certain cases with ease, and vice versa. +Це зроблено для сумісності з об'єктом `Map`, в якому колбек `forEach` має 3 аргумента. Виглядає трохи дивно, але в деяких випадках може допомогти легко замінити `Map` на `Set` і навпаки. -The same methods `Map` has for iterators are also supported: +`Set` має ті ж вбудовані методи, що і `Map`: -- `set.keys()` -- returns an iterable object for values, -- `set.values()` -- same as `set.keys()`, for compatibility with `Map`, -- `set.entries()` -- returns an iterable object for entries `[value, value]`, exists for compatibility with `Map`. +- `set.keys()` -- повертає об'єкт-ітератор для значень, +- `set.values()` -- те ж семе, що `set.keys()`, для сумісності з `Map`, +- `set.entries()` -- повертає об'єкт-ітератор для пар виду `[значення, значення]`, присутній для сумісності з `Map`. -## Summary +## Висновок -`Map` -- is a collection of keyed values. +`Map` -- це колекція ключ/значення. -Methods and properties: +Методи і властивості: -- `new Map([iterable])` -- creates the map, with optional `iterable` (e.g. array) of `[key,value]` pairs for initialization. -- `map.set(key, value)` -- stores the value by the key, returns the map itself. -- `map.get(key)` -- returns the value by the key, `undefined` if `key` doesn't exist in map. -- `map.has(key)` -- returns `true` if the `key` exists, `false` otherwise. -- `map.delete(key)` -- removes the value by the key, returns `true` if `key` existed at the moment of the call, otherwise `false`. -- `map.clear()` -- removes everything from the map. -- `map.size` -- returns the current element count. +- `new Map([iterable])` -- створює колекцію, можна вказати `об'єкт-ітератор` (зазвичай масив) з пар `[ключ, значення]` для ініціалізації. +- `map.set(key, value)` -- записує по ключу `key` значення `value`. +- `map.get(key)` -- повертає значення по `key` або `undefined`, якщо ключ `key` відсутній. +- `map.has(key)` -- повертає `true`, якщо ключ `key` присутній в колекції, інакше false +- `map.delete(key)` -- видаляє елемент по ключу key. видаляє елемент по ключу key. Повертає `true`, якщо `key` існує на момент виклику функції, інакше `false`. +- `map.clear()` -- очищає колекцію від всіх елементів. +- `map.size` -- повертає поточну кількість елементів. -The differences from a regular `Object`: +Відмінності від звичайного об'єкта `Object`: -- Any keys, objects can be keys. -- Additional convenient methods, the `size` property. +- Що завгодно може бути ключем, в тому числі і об'єкти. +- Є додаткові методи, властивість `size`. -`Set` -- is a collection of unique values. +`Set` -- колекція унікальних значень, так звана «множина». -Methods and properties: +Методи і властивості: -- `new Set([iterable])` -- creates the set, with optional `iterable` (e.g. array) of values for initialization. -- `set.add(value)` -- adds a value (does nothing if `value` exists), returns the set itself. -- `set.delete(value)` -- removes the value, returns `true` if `value` existed at the moment of the call, otherwise `false`. -- `set.has(value)` -- returns `true` if the value exists in the set, otherwise `false`. -- `set.clear()` -- removes everything from the set. -- `set.size` -- is the elements count. +- `new Set([iterable])` -- створює `Set`, можна вказати `об'єкт-ітератор` (зазвичай масив). +- `set.add(value)` -- додає значення (якщо воно вже є, то нічого не робить), повертає той же об'єкт `set`. +- `set.delete(value)` -- видаляє значення, повертає `true` якщо `value` було в множині на момент виклику, інакше `false`. +- `set.has(value)` -- повертає `true`, якщо значення присутній в множині, інакше `false`. +- `set.clear()` -- видаляє всі наявні значення. +- `set.size` -- повертає кількість елементів у множині. -Iteration over `Map` and `Set` is always in the insertion order, so we can't say that these collections are unordered, but we can't reorder elements or directly get an element by its number. +Перебір `Map` і `Set` завжди здійснюється в порядку додавання елементів, так що не можна сказати, що це - невпорядковані колекції, але поміняти порядок елементів або отримати елемент безпосередньо по його номеру не можна. From e739584051b7781fab1d9605a7c55a0da47e6cf3 Mon Sep 17 00:00:00 2001 From: Vasyl Onopriienko Date: Fri, 23 Jul 2021 10:45:01 +0300 Subject: [PATCH 02/12] Update translation --- .../07-map-set/01-array-unique-map/task.md | 2 +- .../07-map-set/02-filter-anagrams/solution.md | 2 +- .../07-map-set/02-filter-anagrams/task.md | 2 +- 1-js/05-data-types/07-map-set/article.md | 88 +++++++++---------- 4 files changed, 47 insertions(+), 47 deletions(-) diff --git a/1-js/05-data-types/07-map-set/01-array-unique-map/task.md b/1-js/05-data-types/07-map-set/01-array-unique-map/task.md index a58cb27f9..1c2a61acb 100644 --- a/1-js/05-data-types/07-map-set/01-array-unique-map/task.md +++ b/1-js/05-data-types/07-map-set/01-array-unique-map/task.md @@ -22,6 +22,6 @@ let values = ["Hare", "Krishna", "Hare", "Krishna", alert( unique(values) ); // Hare, Krishna, :-O ``` -P.S. В прикладі ми використали рядки, але можуть бути значення будь якого типу. +P.S. В прикладі ми використали рядки, але можуть бути значення будь-якого типу. P.P.S. Використайте `Set` для формування множини унікальних значень. diff --git a/1-js/05-data-types/07-map-set/02-filter-anagrams/solution.md b/1-js/05-data-types/07-map-set/02-filter-anagrams/solution.md index af831bfd7..63bae9c3e 100644 --- a/1-js/05-data-types/07-map-set/02-filter-anagrams/solution.md +++ b/1-js/05-data-types/07-map-set/02-filter-anagrams/solution.md @@ -52,7 +52,7 @@ map.set(sorted, word); Якщо ми коли-небудь ще зустрінемо слово в тій же відсортованої формі, тоді це слово перезапише значення з тим же ключем в об'єкті. Таким чином, декільком словами у нас буде завжди відповідати одна відсортована форма. -Врешті-решт `Array.from(map.values())` приймає значення об'єкту-ітератора 'Map' (в даному випадку нам не потрібні ключі) і повертає їх у вигляді масиву. +Врешті-решт `Array.from(map.values())` приймає значення об'єкта-ітератора 'Map' (в цьому випадку нам не потрібні ключі) і повертає їх у вигляді масиву. Тут ми також можемо використовувати звичайний об'єкт замість `Map`, тому що ключі - це рядки. diff --git a/1-js/05-data-types/07-map-set/02-filter-anagrams/task.md b/1-js/05-data-types/07-map-set/02-filter-anagrams/task.md index b467f8fb7..0ba78ec0f 100644 --- a/1-js/05-data-types/07-map-set/02-filter-anagrams/task.md +++ b/1-js/05-data-types/07-map-set/02-filter-anagrams/task.md @@ -2,7 +2,7 @@ importance: 4 --- -# Відфілтруйте анаграми +# Відфільтруйте анаграми [Анаграми](https://en.wikipedia.org/wiki/Anagram) -- це слова, у яких ті ж букви в тій же кількості, але вони розташовуються в іншому порядку. diff --git a/1-js/05-data-types/07-map-set/article.md b/1-js/05-data-types/07-map-set/article.md index 44a1655e7..b2cd10d1a 100644 --- a/1-js/05-data-types/07-map-set/article.md +++ b/1-js/05-data-types/07-map-set/article.md @@ -12,7 +12,7 @@ [Map](mdn:js/Map) це колекція ключ/значення, як і `Object`. Але основна відмінність полягає в тому, що `Map` дозволяє мати ключі будь-якого типу. -Методи і властивості: +Методи та властивості: - `new Map()` -- створює колекцію. - `map.set(key, value)` -- зберігає значення `value` за ключем `key`. @@ -27,7 +27,7 @@ ```js run let map = new Map(); -map.set('1', 'str1'); // рядок в якості ключа +map.set('1', 'str1'); // рядок як ключ map.set(1, 'num1'); // цифра як ключ map.set(true, 'bool1'); // булеве значення як ключ @@ -42,7 +42,7 @@ alert( map.size ); // 3 Як ми бачимо, на відміну від об'єктів, ключі не були приведені до рядків. Можна використовувати будь-які типи даних для ключів. ```smart header="`map[key]` не є правильним методом використання `Map`" -Хоча `map[key]` також працює, але такий спосіб присвоєння `map[key] = 2` використовує колекцію як звичайний JavaScript об'єкт, тобто накладає відповідні обмеження (тільки типи рядки/символи як ключі і так далі). +Хоча `map[key]` також працює, але такий спосіб присвоєння `map[key] = 2` використовує колекцію як звичайний JavaScript об'єкт, тобто накладає відповідні обмеження (тільки типи рядки/символи як ключі та інше). Таким чином ми повинні користуватись `map` методами: `set`, `get` і так далі. ``` @@ -54,7 +54,7 @@ alert( map.size ); // 3 ```js run let john = { name: "John" }; -// давайте збережемо кількість відвідувань для кожного користувача +// збережімо кількість відвідувань для кожного користувача let visitsCountMap = new Map(); // об'єкт john -- це ключ для значення в колекції Map @@ -63,7 +63,7 @@ visitsCountMap.set(john, 123); alert( visitsCountMap.get(john) ); // 123 ``` -Використання об'єктів в якості ключів -- це одна з відомих і часто застосовуваних можливостей колекції Map. Ми можемо використати ключі-рядки для об'єкту `Object`, але для ключів-об'єктів -- вже ні. +Використання об'єктів як ключів -- це одна з відомих і часто застосовуваних можливостей колекції Map. Ми можемо використати ключі-рядки для об'єкта `Object`, але для ключів-об'єктів -- вже ні. Спробуємо замінити Map на Object в прикладі вище:: @@ -78,14 +78,14 @@ visitsCountObj[john] = 123; // використаємо `john` об'єкт як *!* // Ось як це було записано! -alert( visitsCountObj["[object Object]"] ); // 123 +alert( visitsCountObj["[object Object]"] ); // 123 */!* ``` -Так як `visitsCountObj` -- це об'єкт, він конвертує всі ключі, такі як `john` і `ben`, до рядку `"[object Object]"`. Це однозначно не той результат, який ми очікуємо. +Оскільки `visitsCountObj` -- це об'єкт, він конвертує всі ключі, такі як `john` і `ben`, до рядка `"[object Object]"`. Це однозначно не той результат, який ми очікуємо. -```smart header="Як об'єкт `Map` порінює ключі" -Щоб порівняти ключі, об'єкт `Map` використовує алгоритм [SameValueZero](https://tc39.github.io/ecma262/#sec-samevaluezero). Це майже таке ж порівняння, що і `===`, з тією лише різницею, що `NaN` вважається рівним `NaN`. Таким чином `NaN` може також бути використаний як ключ. +```smart header="Як об'єкт `Map` порівнює ключі" +Порівнюючи ключі, об'єкт `Map` використовує алгоритм [SameValueZero](https://tc39.github.io/ecma262/#sec-samevaluezero). Це майже таке ж порівняння, що і `===`, з тією лише різницею, що `NaN` вважається рівним `NaN`. Таким чином `NaN` може також бути використаний як ключ. Цей алгоритм не може бути замінений або модифікований. ``` @@ -95,8 +95,8 @@ alert( visitsCountObj["[object Object]"] ); // 123 ```js map.set('1', 'str1') - .set(1, 'num1') - .set(true, 'bool1'); +.set(1, 'num1') +.set(true, 'bool1'); ``` ```` @@ -107,30 +107,30 @@ map.set('1', 'str1') - `map.keys()` -- повертає об'єкт-ітератор для ключів, - `map.values()` -- повертає об'єкт-ітератор для значень, -- `map.entries()` -- повертає об'єкт-ітератор зі значеннями виду [ключ, значення], цей варіант використовується за умовчанням в for..of. +- `map.entries()` -- повертає об'єкт-ітератор зі значеннями виду [ключ, значення], цей варіант використовується за умовчанням у `for..of`. Наприклад: ```js run let recipeMap = new Map([ - ['cucumber', 500], - ['tomatoes', 350], - ['onion', 50] +['cucumber', 500], +['tomatoes', 350], +['onion', 50] ]); // перебираємо ключі (овочі) for (let vegetable of recipeMap.keys()) { - alert(vegetable); // cucumber, tomatoes, onion +alert(vegetable); // cucumber, tomatoes, onion } // перебираємо значення (числа) for (let amount of recipeMap.values()) { - alert(amount); // 500, 350, 50 +alert(amount); // 500, 350, 50 } -// перебір елементів в форматі [ключ, значення] +// перебір елементів у форматі [ключ, значення] for (let entry of recipeMap) { // те ж саме, що recipeMap.entries() - alert(entry); // cucumber,500 (і так далі) +alert(entry); // cucumber,500 (і так далі) } ``` @@ -143,7 +143,7 @@ for (let entry of recipeMap) { // те ж саме, що recipeMap.entries() ```js // виконуємо функцію для кожної пари (ключ, значення) recipeMap.forEach( (value, key, map) => { - alert(`${key}: ${value}`); // cucumber: 500 і так далі +alert(`${key}: ${value}`); // cucumber: 500 і так далі }); ``` @@ -156,7 +156,7 @@ recipeMap.forEach( (value, key, map) => { let map = new Map([ ['1', 'str1'], [1, 'num1'], - [true, 'bool1'] +[true, 'bool1'] ]); alert( map.get('1') ); // str1 @@ -164,12 +164,12 @@ alert( map.get('1') ); // str1 Якщо у нас вже є звичайний об'єкт, і ми хотіли б створити `Map` з нього, то допоможе вбудований метод [Object.entries(obj)](mdn:js/Object/entries) який отримує об'єкт і повертає масив пар ключ-значення для нього, як раз в цьому форматі. -Таким чином ми можемо створити `Map` з об'єкту наступним чином: +Таким чином ми можемо створити `Map` з об'єкта наступним чином: ```js run let obj = { - name: "John", - age: 30 +name: "John", +age: 30 }; *!* @@ -179,20 +179,20 @@ let map = new Map(Object.entries(obj)); alert( map.get('name') ); // John ``` -Тут, `Object.entries` повертає масив пар ключ-значення: `[ ["name","John"], ["age", 30] ]`. Це саме те, що потрібно для створення `Map`. +В цьому випадку `Object.entries` повертає масив пар ключ-значення: `[ ["name","John"], ["age", 30] ]`. Це саме те, що потрібно для створення `Map`. ## Object.fromEntries: Object з Map -Ми щойно створювали `Map` з простого об'єкту за допомогою `Object.entries(obj)`. +Ми щойно створювали `Map` з простого об'єкта за допомогою `Object.entries(obj)`. Ми можемо використати `Object.fromEntries` метод, який виконає зворотну дію: трансформує отриманий масив пар `[ключ, значення]` в об'єкт. Наприклад: ```js run let prices = Object.fromEntries([ - ['banana', 1], - ['orange', 2], - ['meat', 4] +['banana', 1], +['orange', 2], +['meat', 4] ]); // now prices = { banana: 1, orange: 2, meat: 4 } @@ -206,7 +206,7 @@ alert(prices.orange); // 2 Ось як це зробити: -```js run +```js run let map = new Map(); map.set('banana', 1); map.set('orange', 2); @@ -229,7 +229,7 @@ alert(obj.orange); // 2 let obj = Object.fromEntries(map); // прибрати .entries() ``` -Це те ж саме, так як `Object.fromEntries` чекає аргументом об'єкт-ітератор, не обов'язково масив. А перебір `map` якраз повертає пари ключ/значення, як і `map.entries()`. Так що в підсумку ми матимемо звичайний об'єкт з тими ж ключами/значеннями, що і в `map`. +Це те ж саме, оскільки `Object.fromEntries` чекає аргументом об'єкт-ітератор, не обов'язково масив. А перебір `map` якраз повертає пари ключ/значення, як і `map.entries()`. Так що в підсумку ми матимемо звичайний об'єкт з тими ж ключами/значеннями, що і в `map`. ## Set @@ -244,7 +244,7 @@ let obj = Object.fromEntries(map); // прибрати .entries() - `set.clear()` -- видаляє всі значення множини `Set`. - `set.size` -- повертає кількість елементів в множині. -Родзинкою `Set` є виклики `set.add(value)`, що повторюються з однаковими значеннями `value`. Повторні виклики цього методу не змінюють об'єкт `Set`. Це причина того, що кожне значення з'являється тільки один раз. +Родзинкою `Set` є виклики `set.add(value)`, що повторюються з однаковими значеннями `value`. Повторні виклики цього методу не змінюють об'єкт `Set`. Це причина того, що кожне значення з'являється тільки один раз. Наприклад, ми очікуємо гостей, і нам необхідно скласти їх список. Але повторні записи не повинні призводити до дублікатів. Кожен гість повинен з'явитися в списку лише один раз. @@ -268,15 +268,15 @@ set.add(mary); alert( set.size ); // 3 for (let user of set) { - alert(user.name); // John (тоді Pete і Mary) +alert(user.name); // John (тоді Pete і Mary) } ``` -Альтернативою множини `Set``'ї може виступати масив для зберігання гостей і додатковий код для перевірки вже наявного елемента за допомогою [arr.find](mdn:js/Array/find). Але в цьому випадку буде гірша продуктивність, тому що `arr.find` проходить весь масив для перевірки наявності елемента. Множина `Set` краще оптимізована для перевірки унікальності. +Альтернативою множини `Set` може виступати масив для зберігання гостей і додатковий код для перевірки вже наявного елемента за допомогою [arr.find](mdn:js/Array/find). Але в цьому випадку буде гірша продуктивність, тому що `arr.find` проходить весь масив для перевірки наявності елемента. Множина `Set` краще оптимізована для перевірки унікальності. ## Перебір об'єкта Set -Ми можемо перебрати вміст об'єкта 'set' як за допомогою методу 'for..of', так і використовуючи 'forEach': +Ми можемо перебрати вміст об'єкта `set` як за допомогою методу `for..of`, так і використовуючи `forEach`: ```js run let set = new Set(["oranges", "apples", "bananas"]); @@ -285,31 +285,31 @@ for (let value of set) alert(value); // те ж саме з forEach: set.forEach((value, valueAgain, set) => { - alert(value); +alert(value); }); ``` -Зауважимо забавну річ. Функція в `forEach` у `Set` має 3 аргумента: значення `value`, потім знову *те ж саме значення* `valueAgain`, і тільки потім цільовий об'єкт. Це дійсно так, значення з'являється в списку аргументів двічі. +Зауважимо цікаву річ. Функція в `forEach` у `Set` має 3 аргументи: значення 'value', потім знову *те ж саме значення* 'valueAgain', і тільки потім цільовий об'єкт. Це дійсно так, значення з'являється в списку аргументів двічі. Це зроблено для сумісності з об'єктом `Map`, в якому колбек `forEach` має 3 аргумента. Виглядає трохи дивно, але в деяких випадках може допомогти легко замінити `Map` на `Set` і навпаки. `Set` має ті ж вбудовані методи, що і `Map`: - `set.keys()` -- повертає об'єкт-ітератор для значень, -- `set.values()` -- те ж семе, що `set.keys()`, для сумісності з `Map`, +- `set.values()` -- те ж саме, що `set.keys()`, для сумісності з `Map`, - `set.entries()` -- повертає об'єкт-ітератор для пар виду `[значення, значення]`, присутній для сумісності з `Map`. ## Висновок `Map` -- це колекція ключ/значення. -Методи і властивості: +Методи та властивості: - `new Map([iterable])` -- створює колекцію, можна вказати `об'єкт-ітератор` (зазвичай масив) з пар `[ключ, значення]` для ініціалізації. -- `map.set(key, value)` -- записує по ключу `key` значення `value`. + - `map.set(key, value)` -- записує по ключу `key` значення `value`. - `map.get(key)` -- повертає значення по `key` або `undefined`, якщо ключ `key` відсутній. -- `map.has(key)` -- повертає `true`, якщо ключ `key` присутній в колекції, інакше false -- `map.delete(key)` -- видаляє елемент по ключу key. видаляє елемент по ключу key. Повертає `true`, якщо `key` існує на момент виклику функції, інакше `false`. +- `map.has(key)` -- повертає `true`, якщо ключ `key` присутній в колекції, інакше `false`. +- `map.delete(key)` -- видаляє елемент по ключу `key`. Повертає `true`, якщо `key` існує на момент виклику функції, інакше `false`. - `map.clear()` -- очищає колекцію від всіх елементів. - `map.size` -- повертає поточну кількість елементів. @@ -320,7 +320,7 @@ set.forEach((value, valueAgain, set) => { `Set` -- колекція унікальних значень, так звана «множина». -Методи і властивості: +Методи та властивості: - `new Set([iterable])` -- створює `Set`, можна вказати `об'єкт-ітератор` (зазвичай масив). - `set.add(value)` -- додає значення (якщо воно вже є, то нічого не робить), повертає той же об'єкт `set`. @@ -329,4 +329,4 @@ set.forEach((value, valueAgain, set) => { - `set.clear()` -- видаляє всі наявні значення. - `set.size` -- повертає кількість елементів у множині. -Перебір `Map` і `Set` завжди здійснюється в порядку додавання елементів, так що не можна сказати, що це - невпорядковані колекції, але поміняти порядок елементів або отримати елемент безпосередньо по його номеру не можна. +Перебір `Map` і `Set` завжди здійснюється в порядку додавання елементів, так що не можна сказати, що це невпорядковані колекції, але поміняти порядок елементів або отримати елемент безпосередньо по його номеру не можна. From 37bcae984af2038874bd051036bc8773ae7376ac Mon Sep 17 00:00:00 2001 From: Vasyl Onopriienko <2588425+Regnised@users.noreply.github.com> Date: Fri, 23 Jul 2021 11:12:24 +0300 Subject: [PATCH 03/12] Fix word --- 1-js/05-data-types/07-map-set/03-iterable-keys/task.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/05-data-types/07-map-set/03-iterable-keys/task.md b/1-js/05-data-types/07-map-set/03-iterable-keys/task.md index 153dce513..8cb89fdaa 100644 --- a/1-js/05-data-types/07-map-set/03-iterable-keys/task.md +++ b/1-js/05-data-types/07-map-set/03-iterable-keys/task.md @@ -4,7 +4,7 @@ importance: 5 # Перебираємо ключі -Ми хотіли б отримати масив ключів 'map.keys()' в змінну і далі працювати з ними, наприклад, застосувати метод `.push`. +Ми хотіли б отримати масив ключів `map.keys()` в змінну і далі працювати з ними, наприклад, застосувати метод `.push`. Але так не спрацює: From 4c8d232e35e0f8c5fad3bb3509c4d5d71c9e4165 Mon Sep 17 00:00:00 2001 From: Vasyl Onopriienko <2588425+Regnised@users.noreply.github.com> Date: Mon, 26 Jul 2021 00:44:21 +0300 Subject: [PATCH 04/12] Update 1-js/05-data-types/07-map-set/article.md Co-authored-by: Taras --- 1-js/05-data-types/07-map-set/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/05-data-types/07-map-set/article.md b/1-js/05-data-types/07-map-set/article.md index b2cd10d1a..69abb6cc2 100644 --- a/1-js/05-data-types/07-map-set/article.md +++ b/1-js/05-data-types/07-map-set/article.md @@ -16,7 +16,7 @@ - `new Map()` -- створює колекцію. - `map.set(key, value)` -- зберігає значення `value` за ключем `key`. -- `map.get(key)` -- повертає значення за ключем, повертає `undefined` якщо `key` не існує в колекції. +- `map.get(key)` -- повертає значення за ключем; повертає `undefined` якщо `key` немає в колекції. - `map.has(key)` -- повертає `true` якщо `key` існує, інакше `false`. - `map.delete(key)` -- видаляє елемент по ключу. - `map.clear()` -- видаляє всі елементи колекції. From 915ffdbd1f5c2a142e604310aacf5a9c15167016 Mon Sep 17 00:00:00 2001 From: Vasyl Onopriienko <2588425+Regnised@users.noreply.github.com> Date: Mon, 26 Jul 2021 00:45:19 +0300 Subject: [PATCH 05/12] Update 1-js/05-data-types/07-map-set/article.md Co-authored-by: Taras --- 1-js/05-data-types/07-map-set/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/05-data-types/07-map-set/article.md b/1-js/05-data-types/07-map-set/article.md index 69abb6cc2..e9ea1c9b6 100644 --- a/1-js/05-data-types/07-map-set/article.md +++ b/1-js/05-data-types/07-map-set/article.md @@ -31,7 +31,7 @@ map.set('1', 'str1'); // рядок як ключ map.set(1, 'num1'); // цифра як ключ map.set(true, 'bool1'); // булеве значення як ключ -// пам'ятайте, звичайний об'єкт `Object` призводить ключі до рядків? +// пам’ятаєте звичайний об’єкт `Object`? Він перетворює всі ключі в рядок // Map зберігає тип ключів, так що в цьому випадку ми отримаємо 2 різних значення: alert( map.get(1) ); // 'num1' alert( map.get('1') ); // 'str1' From 5585083feab96e9f706ff557e0127d74f637ef78 Mon Sep 17 00:00:00 2001 From: Vasyl Onopriienko <2588425+Regnised@users.noreply.github.com> Date: Mon, 26 Jul 2021 00:46:14 +0300 Subject: [PATCH 06/12] Update 1-js/05-data-types/07-map-set/article.md Co-authored-by: Taras --- 1-js/05-data-types/07-map-set/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/05-data-types/07-map-set/article.md b/1-js/05-data-types/07-map-set/article.md index e9ea1c9b6..c022eb9b2 100644 --- a/1-js/05-data-types/07-map-set/article.md +++ b/1-js/05-data-types/07-map-set/article.md @@ -63,7 +63,7 @@ visitsCountMap.set(john, 123); alert( visitsCountMap.get(john) ); // 123 ``` -Використання об'єктів як ключів -- це одна з відомих і часто застосовуваних можливостей колекції Map. Ми можемо використати ключі-рядки для об'єкта `Object`, але для ключів-об'єктів -- вже ні. +Об’єкти в якості ключів -- це одна з відомих можливостей колекції `Map`, яку часто використовують. У звичайному об’єкті `Object`, ми можемо використати ключі-рядки, проте ключі-об’єкти -- вже ні. Спробуємо замінити Map на Object в прикладі вище:: From 44a0613fc90b6ad6c91280a719f00432bcf41793 Mon Sep 17 00:00:00 2001 From: Vasyl Onopriienko <2588425+Regnised@users.noreply.github.com> Date: Mon, 26 Jul 2021 00:46:29 +0300 Subject: [PATCH 07/12] Update 1-js/05-data-types/07-map-set/article.md Co-authored-by: Taras --- 1-js/05-data-types/07-map-set/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/05-data-types/07-map-set/article.md b/1-js/05-data-types/07-map-set/article.md index c022eb9b2..8c4f5924a 100644 --- a/1-js/05-data-types/07-map-set/article.md +++ b/1-js/05-data-types/07-map-set/article.md @@ -73,7 +73,7 @@ let ben = { name: "Ben" }; let visitsCountObj = {}; // використаємо об'єкт -visitsCountObj[ben] = 234; // використаємо `ben` об'єкт як ключ +visitsCountObj[ben] = 234; // використаємо об’єкт `ben` як ключ visitsCountObj[john] = 123; // використаємо `john` об'єкт як ключ, `ben` об'єкт буде перезаписаний *!* From 7b2db3856b569ea93dcc0b7826c9921b9e965719 Mon Sep 17 00:00:00 2001 From: Vasyl Onopriienko <2588425+Regnised@users.noreply.github.com> Date: Mon, 26 Jul 2021 00:46:46 +0300 Subject: [PATCH 08/12] Update 1-js/05-data-types/07-map-set/article.md Co-authored-by: Taras --- 1-js/05-data-types/07-map-set/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/05-data-types/07-map-set/article.md b/1-js/05-data-types/07-map-set/article.md index 8c4f5924a..009e95986 100644 --- a/1-js/05-data-types/07-map-set/article.md +++ b/1-js/05-data-types/07-map-set/article.md @@ -71,7 +71,7 @@ alert( visitsCountMap.get(john) ); // 123 let john = { name: "John" }; let ben = { name: "Ben" }; -let visitsCountObj = {}; // використаємо об'єкт +let visitsCountObj = {}; // оголосимо звичайний об’єкт visitsCountObj[ben] = 234; // використаємо об’єкт `ben` як ключ visitsCountObj[john] = 123; // використаємо `john` об'єкт як ключ, `ben` об'єкт буде перезаписаний From a03cc542e3a5556dc802a9701f2f3469b0c99cdc Mon Sep 17 00:00:00 2001 From: Vasyl Onopriienko <2588425+Regnised@users.noreply.github.com> Date: Mon, 26 Jul 2021 00:47:35 +0300 Subject: [PATCH 09/12] Update 1-js/05-data-types/07-map-set/article.md Co-authored-by: Taras --- 1-js/05-data-types/07-map-set/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/05-data-types/07-map-set/article.md b/1-js/05-data-types/07-map-set/article.md index 009e95986..6b8978c3a 100644 --- a/1-js/05-data-types/07-map-set/article.md +++ b/1-js/05-data-types/07-map-set/article.md @@ -82,7 +82,7 @@ alert( visitsCountObj["[object Object]"] ); // 123 */!* ``` -Оскільки `visitsCountObj` -- це об'єкт, він конвертує всі ключі, такі як `john` і `ben`, до рядка `"[object Object]"`. Це однозначно не той результат, який ми очікуємо. +Оскільки `visitsCountObj` -- це об’єкт, він конвертує всі ключі типу `Object` (такі як `john` і `ben`) до рядка `"[object Object]"`. Це однозначно не той результат, який ми очікуємо. ```smart header="Як об'єкт `Map` порівнює ключі" Порівнюючи ключі, об'єкт `Map` використовує алгоритм [SameValueZero](https://tc39.github.io/ecma262/#sec-samevaluezero). Це майже таке ж порівняння, що і `===`, з тією лише різницею, що `NaN` вважається рівним `NaN`. Таким чином `NaN` може також бути використаний як ключ. From ee5e34696cea542ffd34d41868fea8c51cc25626 Mon Sep 17 00:00:00 2001 From: Vasyl Onopriienko <2588425+Regnised@users.noreply.github.com> Date: Mon, 26 Jul 2021 11:34:35 +0300 Subject: [PATCH 10/12] Update 1-js/05-data-types/07-map-set/article.md Co-authored-by: Taras --- 1-js/05-data-types/07-map-set/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/05-data-types/07-map-set/article.md b/1-js/05-data-types/07-map-set/article.md index 6b8978c3a..a4d42210a 100644 --- a/1-js/05-data-types/07-map-set/article.md +++ b/1-js/05-data-types/07-map-set/article.md @@ -65,7 +65,7 @@ alert( visitsCountMap.get(john) ); // 123 Об’єкти в якості ключів -- це одна з відомих можливостей колекції `Map`, яку часто використовують. У звичайному об’єкті `Object`, ми можемо використати ключі-рядки, проте ключі-об’єкти -- вже ні. -Спробуємо замінити Map на Object в прикладі вище:: +Розгляньмо такий приклад: ```js run let john = { name: "John" }; From 9d95f578dade5683e8c32dcc1168ade261718c44 Mon Sep 17 00:00:00 2001 From: Vasyl Onopriienko <2588425+Regnised@users.noreply.github.com> Date: Mon, 26 Jul 2021 11:53:18 +0300 Subject: [PATCH 11/12] Map and Set: spaces and other fixes --- .../07-map-set/03-iterable-keys/task.md | 24 ++++ 1-js/05-data-types/07-map-set/article.md | 104 +++++++++--------- 2 files changed, 76 insertions(+), 52 deletions(-) diff --git a/1-js/05-data-types/07-map-set/03-iterable-keys/task.md b/1-js/05-data-types/07-map-set/03-iterable-keys/task.md index 8cb89fdaa..f7b345d96 100644 --- a/1-js/05-data-types/07-map-set/03-iterable-keys/task.md +++ b/1-js/05-data-types/07-map-set/03-iterable-keys/task.md @@ -22,3 +22,27 @@ keys.push("more"); ``` Чому? Що потрібно виправити в коді, щоб `keys.push` працював? +importance: 5 + +--- + +# Перебираємо ключі + +Ми хотіли б отримати масив ключів `map.keys()` в змінну і далі працювати з ними, наприклад, застосувати метод `.push`. + +Але так не спрацює: + +```js run +let map = new Map(); + +map.set("name", "John"); + +let keys = map.keys(); + +*!* +// Помилка: keys.push -- це не функція +keys.push("more"); +*/!* +``` + +Чому? Що потрібно виправити в коді, щоб `keys.push` працював? diff --git a/1-js/05-data-types/07-map-set/article.md b/1-js/05-data-types/07-map-set/article.md index b2cd10d1a..bb74151d2 100644 --- a/1-js/05-data-types/07-map-set/article.md +++ b/1-js/05-data-types/07-map-set/article.md @@ -3,7 +3,7 @@ Зараз ми знаємо про наступні складні структури даних: -- Об'єкти для зберігання іменованих колекцій. +- Об’єкти для зберігання іменованих колекцій. - Масиви для зберігання впорядкованих колекцій. Але цього не завжди достатньо в реальному житті. Ось чому існують `Map` і `Set`. @@ -31,7 +31,7 @@ map.set('1', 'str1'); // рядок як ключ map.set(1, 'num1'); // цифра як ключ map.set(true, 'bool1'); // булеве значення як ключ -// пам'ятайте, звичайний об'єкт `Object` призводить ключі до рядків? +// пам’ятайте, звичайний об’єкт `Object` призводить ключі до рядків? // Map зберігає тип ключів, так що в цьому випадку ми отримаємо 2 різних значення: alert( map.get(1) ); // 'num1' alert( map.get('1') ); // 'str1' @@ -39,15 +39,15 @@ alert( map.get('1') ); // 'str1' alert( map.size ); // 3 ``` -Як ми бачимо, на відміну від об'єктів, ключі не були приведені до рядків. Можна використовувати будь-які типи даних для ключів. +Як ми бачимо, на відміну від об’єктів, ключі не були приведені до рядків. Можна використовувати будь-які типи даних для ключів. ```smart header="`map[key]` не є правильним методом використання `Map`" -Хоча `map[key]` також працює, але такий спосіб присвоєння `map[key] = 2` використовує колекцію як звичайний JavaScript об'єкт, тобто накладає відповідні обмеження (тільки типи рядки/символи як ключі та інше). +Хоча `map[key]` також працює, але такий спосіб присвоєння `map[key] = 2` використовує колекцію як звичайний JavaScript об’єкт, тобто накладає відповідні обмеження (тільки типи рядки/символи як ключі та інше). Таким чином ми повинні користуватись `map` методами: `set`, `get` і так далі. ``` -**Map також може використовувати об'єкти як ключі.** +**Map також може використовувати об’єкти як ключі.** Наприклад: @@ -57,13 +57,13 @@ let john = { name: "John" }; // збережімо кількість відвідувань для кожного користувача let visitsCountMap = new Map(); -// об'єкт john -- це ключ для значення в колекції Map +// об’єкт john -- це ключ для значення в колекції Map visitsCountMap.set(john, 123); alert( visitsCountMap.get(john) ); // 123 ``` -Використання об'єктів як ключів -- це одна з відомих і часто застосовуваних можливостей колекції Map. Ми можемо використати ключі-рядки для об'єкта `Object`, але для ключів-об'єктів -- вже ні. +Використання об’єктів як ключів -- це одна з відомих і часто застосовуваних можливостей колекції Map. Ми можемо використати ключі-рядки для об’єкта `Object`, але для ключів-об’єктів -- вже ні. Спробуємо замінити Map на Object в прикладі вище:: @@ -71,10 +71,10 @@ alert( visitsCountMap.get(john) ); // 123 let john = { name: "John" }; let ben = { name: "Ben" }; -let visitsCountObj = {}; // використаємо об'єкт +let visitsCountObj = {}; // використаємо об’єкт -visitsCountObj[ben] = 234; // використаємо `ben` об'єкт як ключ -visitsCountObj[john] = 123; // використаємо `john` об'єкт як ключ, `ben` об'єкт буде перезаписаний +visitsCountObj[ben] = 234; // використаємо `ben` об’єкт як ключ +visitsCountObj[john] = 123; // використаємо `john` об’єкт як ключ, `ben` об’єкт буде перезаписаний *!* // Ось як це було записано! @@ -82,16 +82,16 @@ alert( visitsCountObj["[object Object]"] ); // 123 */!* ``` -Оскільки `visitsCountObj` -- це об'єкт, він конвертує всі ключі, такі як `john` і `ben`, до рядка `"[object Object]"`. Це однозначно не той результат, який ми очікуємо. +Оскільки `visitsCountObj` -- це об’єкт, він конвертує всі ключі, такі як `john` і `ben`, до рядка `"[object Object]"`. Це однозначно не той результат, який ми очікуємо. -```smart header="Як об'єкт `Map` порівнює ключі" -Порівнюючи ключі, об'єкт `Map` використовує алгоритм [SameValueZero](https://tc39.github.io/ecma262/#sec-samevaluezero). Це майже таке ж порівняння, що і `===`, з тією лише різницею, що `NaN` вважається рівним `NaN`. Таким чином `NaN` може також бути використаний як ключ. +```smart header="Як `Map` порівнює ключі" +Порівнюючи ключі, об’єкт `Map` використовує алгоритм [SameValueZero](https://tc39.github.io/ecma262/#sec-samevaluezero). Це майже таке ж порівняння, що і `===`, з тією лише різницею, що `NaN` вважається рівним `NaN`. Таким чином `NaN` може також бути використаний як ключ. Цей алгоритм не може бути замінений або модифікований. ``` ````smart header="Послідовні виклики" -Кожен виклик `map.set` повертає об'єкт map, таким чином ми можемо об'єднати виклики в ланцюжок: +Кожен виклик `map.set` повертає об’єкт map, таким чином ми можемо об’єднати виклики в ланцюжок: ```js map.set('1', 'str1') @@ -105,9 +105,9 @@ map.set('1', 'str1') Для перебору колекції Map є 3 метода: -- `map.keys()` -- повертає об'єкт-ітератор для ключів, -- `map.values()` -- повертає об'єкт-ітератор для значень, -- `map.entries()` -- повертає об'єкт-ітератор зі значеннями виду [ключ, значення], цей варіант використовується за умовчанням у `for..of`. +- `map.keys()` -- повертає об’єкт-ітератор для ключів, +- `map.values()` -- повертає об’єкт-ітератор для значень, +- `map.entries()` -- повертає об’єкт-ітератор зі значеннями виду [ключ, значення], цей варіант використовується за умовчанням у `for..of`. Наприклад: @@ -120,22 +120,22 @@ let recipeMap = new Map([ // перебираємо ключі (овочі) for (let vegetable of recipeMap.keys()) { -alert(vegetable); // cucumber, tomatoes, onion + alert(vegetable); // cucumber, tomatoes, onion } // перебираємо значення (числа) for (let amount of recipeMap.values()) { -alert(amount); // 500, 350, 50 + alert(amount); // 500, 350, 50 } // перебір елементів у форматі [ключ, значення] for (let entry of recipeMap) { // те ж саме, що recipeMap.entries() -alert(entry); // cucumber,500 (і так далі) + alert(entry); // cucumber,500 (і так далі) } ``` ```smart header="Використовується порядок вставки" -На відміну від звичайних об'єктів `Object`, в `Map` перебір відбувається в тому ж порядку, в якому відбувалося додавання елементів. +На відміну від звичайних об’єктів `Object`, в `Map` перебір відбувається в тому ж порядку, в якому відбувалося додавання елементів. ``` Крім цього, `Map` має вбудований метод `forEach`, схожий з вбудованим методом масивів `Array`: @@ -143,13 +143,13 @@ alert(entry); // cucumber,500 (і так далі) ```js // виконуємо функцію для кожної пари (ключ, значення) recipeMap.forEach( (value, key, map) => { -alert(`${key}: ${value}`); // cucumber: 500 і так далі + alert(`${key}: ${value}`); // cucumber: 500 і так далі }); ``` ## Object.entries: Map з Object -При створенні `Map` ми можемо вказати масив (або інший об'єкт-ітератор) з парами ключ-значення для ініціалізації, як тут: +При створенні `Map` ми можемо вказати масив (або інший об’єкт-ітератор) з парами ключ-значення для ініціалізації, як тут: ```js run // масив пар [ключ, значення] @@ -162,14 +162,14 @@ let map = new Map([ alert( map.get('1') ); // str1 ``` -Якщо у нас вже є звичайний об'єкт, і ми хотіли б створити `Map` з нього, то допоможе вбудований метод [Object.entries(obj)](mdn:js/Object/entries) який отримує об'єкт і повертає масив пар ключ-значення для нього, як раз в цьому форматі. +Якщо у нас вже є звичайний об’єкт, і ми хотіли б створити `Map` з нього, то допоможе вбудований метод [Object.entries(obj)](mdn:js/Object/entries) який отримує об’єкт і повертає масив пар ключ-значення для нього, як раз в цьому форматі. -Таким чином ми можемо створити `Map` з об'єкта наступним чином: +Таким чином ми можемо створити `Map` з об’єкта наступним чином: ```js run let obj = { -name: "John", -age: 30 + name: "John", + age: 30 }; *!* @@ -184,9 +184,9 @@ alert( map.get('name') ); // John ## Object.fromEntries: Object з Map -Ми щойно створювали `Map` з простого об'єкта за допомогою `Object.entries(obj)`. +Ми щойно створювали `Map` з простого об’єкта за допомогою `Object.entries(obj)`. -Ми можемо використати `Object.fromEntries` метод, який виконає зворотну дію: трансформує отриманий масив пар `[ключ, значення]` в об'єкт. Наприклад: +Ми можемо використати `Object.fromEntries` метод, який виконає зворотну дію: трансформує отриманий масив пар `[ключ, значення]` в об’єкт. Наприклад: ```js run let prices = Object.fromEntries([ @@ -200,9 +200,9 @@ let prices = Object.fromEntries([ alert(prices.orange); // 2 ``` -Ми можемо використати `Object.fromEntries`, щоб отримати звичайний об'єкт з `Map`. +Ми можемо використати `Object.fromEntries`, щоб отримати звичайний об’єкт з `Map`. -Наприклад, ми маємо дані в `Map`, але потрібно їх передати в сторонній код, який чекає простий об'єкт. +Наприклад, ми маємо дані в `Map`, але потрібно їх передати в сторонній код, який чекає простий об’єкт. Ось як це зробити: @@ -213,7 +213,7 @@ map.set('orange', 2); map.set('meat', 4); *!* -let obj = Object.fromEntries(map.entries()); // робимо простий об'єкт (*) +let obj = Object.fromEntries(map.entries()); // робимо простий об’єкт (*) */!* // Готово! @@ -229,24 +229,24 @@ alert(obj.orange); // 2 let obj = Object.fromEntries(map); // прибрати .entries() ``` -Це те ж саме, оскільки `Object.fromEntries` чекає аргументом об'єкт-ітератор, не обов'язково масив. А перебір `map` якраз повертає пари ключ/значення, як і `map.entries()`. Так що в підсумку ми матимемо звичайний об'єкт з тими ж ключами/значеннями, що і в `map`. +Це те ж саме, оскільки `Object.fromEntries` чекає аргументом об’єкт-ітератор, не обов’язково масив. А перебір `map` якраз повертає пари ключ/значення, як і `map.entries()`. Так що в підсумку ми матимемо звичайний об’єкт з тими ж ключами/значеннями, що і в `map`. ## Set -Об'єкт `Set` -- це особливий тип колекції: "множина" значень (без ключів), де кожне значення може з'являтися тільки раз. +Об’єкт `Set` -- це особливий тип колекції: "множина" значень (без ключів), де кожне значення може з’являтися тільки раз. Основні методи: -- `new Set(iterable)` -- створює об'єкт `Set`, якщо аргументом виступає об'єкт-ітератор, тоді значення копіюються в `Set`. -- `set.add(value)` -- додає нове значення до `Set`, повертає об'єкт `Set`. +- `new Set(iterable)` -- створює `Set`, якщо аргументом виступає об’єкт-ітератор, тоді значення копіюються в `Set`. +- `set.add(value)` -- додає нове значення до `Set`, повертає `Set`. - `set.delete(value)` -- видаляє значення з `Set`, повертає `true`, якщо `value` наявне в множині значень на момент виклику методу, інакше `false`. - `set.has(value)` -- повертає `true`, якщо `value` присутнє в множині `Set`, інакше `false`. - `set.clear()` -- видаляє всі значення множини `Set`. - `set.size` -- повертає кількість елементів в множині. -Родзинкою `Set` є виклики `set.add(value)`, що повторюються з однаковими значеннями `value`. Повторні виклики цього методу не змінюють об'єкт `Set`. Це причина того, що кожне значення з'являється тільки один раз. +Родзинкою `Set` є виклики `set.add(value)`, що повторюються з однаковими значеннями `value`. Повторні виклики цього методу не змінюють `Set`. Це причина того, що кожне значення з’являється тільки один раз. -Наприклад, ми очікуємо гостей, і нам необхідно скласти їх список. Але повторні записи не повинні призводити до дублікатів. Кожен гість повинен з'явитися в списку лише один раз. +Наприклад, ми очікуємо гостей, і нам необхідно скласти їх список. Але повторні записи не повинні призводити до дублікатів. Кожен гість повинен з’явитися в списку лише один раз. Множина `Set` -- це саме те, що потрібно для цього: @@ -268,15 +268,15 @@ set.add(mary); alert( set.size ); // 3 for (let user of set) { -alert(user.name); // John (тоді Pete і Mary) + alert(user.name); // John (тоді Pete і Mary) } ``` Альтернативою множини `Set` може виступати масив для зберігання гостей і додатковий код для перевірки вже наявного елемента за допомогою [arr.find](mdn:js/Array/find). Але в цьому випадку буде гірша продуктивність, тому що `arr.find` проходить весь масив для перевірки наявності елемента. Множина `Set` краще оптимізована для перевірки унікальності. -## Перебір об'єкта Set +## Перебір об’єкта Set -Ми можемо перебрати вміст об'єкта `set` як за допомогою методу `for..of`, так і використовуючи `forEach`: +Ми можемо перебрати вміст об’єкта `set` як за допомогою методу `for..of`, так і використовуючи `forEach`: ```js run let set = new Set(["oranges", "apples", "bananas"]); @@ -285,27 +285,27 @@ for (let value of set) alert(value); // те ж саме з forEach: set.forEach((value, valueAgain, set) => { -alert(value); + alert(value); }); ``` -Зауважимо цікаву річ. Функція в `forEach` у `Set` має 3 аргументи: значення 'value', потім знову *те ж саме значення* 'valueAgain', і тільки потім цільовий об'єкт. Це дійсно так, значення з'являється в списку аргументів двічі. +Зауважимо цікаву річ. Функція в `forEach` у `Set` має 3 аргументи: значення 'value', потім знову *те ж саме значення* 'valueAgain', і тільки потім цільовий об’єкт. Це дійсно так, значення з’являється в списку аргументів двічі. -Це зроблено для сумісності з об'єктом `Map`, в якому колбек `forEach` має 3 аргумента. Виглядає трохи дивно, але в деяких випадках може допомогти легко замінити `Map` на `Set` і навпаки. +Це зроблено для сумісності з об’єктом `Map`, в якому колбек `forEach` має 3 аргумента. Виглядає трохи дивно, але в деяких випадках може допомогти легко замінити `Map` на `Set` і навпаки. `Set` має ті ж вбудовані методи, що і `Map`: -- `set.keys()` -- повертає об'єкт-ітератор для значень, +- `set.keys()` -- повертає об’єкт-ітератор для значень, - `set.values()` -- те ж саме, що `set.keys()`, для сумісності з `Map`, -- `set.entries()` -- повертає об'єкт-ітератор для пар виду `[значення, значення]`, присутній для сумісності з `Map`. +- `set.entries()` -- повертає об’єкт-ітератор для пар виду `[значення, значення]`, присутній для сумісності з `Map`. -## Висновок +## Підсумки `Map` -- це колекція ключ/значення. Методи та властивості: -- `new Map([iterable])` -- створює колекцію, можна вказати `об'єкт-ітератор` (зазвичай масив) з пар `[ключ, значення]` для ініціалізації. +- `new Map([iterable])` -- створює колекцію, можна вказати `об’єкт-ітератор` (зазвичай масив) з пар `[ключ, значення]` для ініціалізації. - `map.set(key, value)` -- записує по ключу `key` значення `value`. - `map.get(key)` -- повертає значення по `key` або `undefined`, якщо ключ `key` відсутній. - `map.has(key)` -- повертає `true`, якщо ключ `key` присутній в колекції, інакше `false`. @@ -313,17 +313,17 @@ alert(value); - `map.clear()` -- очищає колекцію від всіх елементів. - `map.size` -- повертає поточну кількість елементів. -Відмінності від звичайного об'єкта `Object`: +Відмінності від звичайного об’єкта `Object`: -- Що завгодно може бути ключем, в тому числі і об'єкти. +- Що завгодно може бути ключем, в тому числі і об’єкти. - Є додаткові методи, властивість `size`. `Set` -- колекція унікальних значень, так звана «множина». Методи та властивості: -- `new Set([iterable])` -- створює `Set`, можна вказати `об'єкт-ітератор` (зазвичай масив). -- `set.add(value)` -- додає значення (якщо воно вже є, то нічого не робить), повертає той же об'єкт `set`. +- `new Set([iterable])` -- створює `Set`, можна вказати `об’єкт-ітератор` (зазвичай масив). +- `set.add(value)` -- додає значення (якщо воно вже є, то нічого не робить), повертає той же об’єкт `set`. - `set.delete(value)` -- видаляє значення, повертає `true` якщо `value` було в множині на момент виклику, інакше `false`. - `set.has(value)` -- повертає `true`, якщо значення присутній в множині, інакше `false`. - `set.clear()` -- видаляє всі наявні значення. From 1be3f056b1b667215559affe4119e0e3e8a80da8 Mon Sep 17 00:00:00 2001 From: Taras Date: Tue, 27 Jul 2021 20:48:11 +0300 Subject: [PATCH 12/12] Update 1-js/05-data-types/07-map-set/02-filter-anagrams/solution.md --- 1-js/05-data-types/07-map-set/02-filter-anagrams/solution.md | 1 + 1 file changed, 1 insertion(+) diff --git a/1-js/05-data-types/07-map-set/02-filter-anagrams/solution.md b/1-js/05-data-types/07-map-set/02-filter-anagrams/solution.md index 63bae9c3e..c80d45c2f 100644 --- a/1-js/05-data-types/07-map-set/02-filter-anagrams/solution.md +++ b/1-js/05-data-types/07-map-set/02-filter-anagrams/solution.md @@ -1,4 +1,5 @@ Щоб знайти всі анаграми, давайте розіб'ємо кожне слово на літери і відсортуємо їх, а потім об'єднаємо масив знову в рядок. Після цього всі анаграми будуть однакові. + Наприклад: ```