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..fb54ea44f 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,13 +2,13 @@ importance: 5 --- -# Filter unique array members +# Lọc các phần tử array duy nhất -Let `arr` be an array. +Đặt `arr` là một array. -Create a function `unique(arr)` that should return an array with unique items of `arr`. +Tạo một hàm `unique(arr)` sẽ trả về một array với các phần tử duy nhất của `arr`. -For instance: +Ví dụ: ```js function unique(arr) { @@ -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. +Tái bút: Ở đây các chuỗi được sử dụng, nhưng có thể là các giá trị thuộc bất kỳ loại nào. -P.P.S. Use `Set` to store unique values. +Tái bút nữa: Sử dụng `Set` để lưu trữ các giá trị duy nhất. 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..3d7836ed6 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,6 @@ -To find all anagrams, let's split every word to letters and sort them. When letter-sorted, all anagrams are same. +Để tìm tất cả các đảo chữ, hãy tách từng từ thành các chữ cái và sắp xếp chúng. Khi sắp xếp theo chữ cái, tất cả các đảo chữ đều giống nhau. -For instance: +Ví dụ: ``` nap, pan -> anp @@ -9,14 +9,14 @@ cheaters, hectares, teachers -> aceehrst ... ``` -We'll use the letter-sorted variants as map keys to store only one value per each key: +Chúng ta sẽ sử dụng các biến thể được sắp xếp theo chữ làm khóa map để chỉ lưu trữ một giá trị cho mỗi khóa: ```js run function aclean(arr) { let map = new Map(); for (let word of arr) { - // split the word by letters, sort them and join back + // tách từ bằng các chữ, sắp xếp chúng và nối lại *!* let sorted = word.toLowerCase().split('').sort().join(''); // (*) */!* @@ -31,9 +31,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 `(*)`. +Việc phân loại chữ cái được thực hiện bởi chuỗi các cuộc gọi trong dòng `(*)`. -For convenience let's split it into multiple lines: +Để thuận tiện, hãy chia nó thành nhiều dòng: ```js let sorted = word // PAN @@ -43,21 +43,21 @@ let sorted = word // PAN .join(''); // anp ``` -Two different words `'PAN'` and `'nap'` receive the same letter-sorted form `'anp'`. +Hai từ khác nhau `'PAN'` và `'nap'` có cùng dạng sắp xếp theo chữ cái `'anp'`. -The next line put the word into the map: +Dòng tiếp theo đưa từ vào 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. +Nếu chúng ta gặp lại một từ có cùng dạng sắp xếp theo chữ cái, thì từ đó sẽ ghi đè lên giá trị trước đó bằng cùng một khóa trong map. Vì vậy, chúng ta sẽ luôn có tối đa một từ cho mỗi mẫu dạng ký tự. -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. +Cuối cùng, `Array.from(map.values())` có thể lặp lại các giá trị map (chúng ta không cần khóa trong kết quả) và trả về một array của chúng. -Here we could also use a plain object instead of the `Map`, because keys are strings. +Ở đây chúng ta cũng có thể sử dụng một đối tượng đơn giản thay vì `Map`, vì các khóa là các chuỗi. -That's how the solution can look: +Đó là cách giải pháp có thể giống: ```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..1ba1c6f30 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 +# Lọc đảo chữ -[Anagrams](https://en.wikipedia.org/wiki/Anagram) are words that have the same number of same letters, but in different order. +[Đảo chữ](https://vi.wikipedia.org/wiki/Phép_đảo_chữ) là những từ có cùng số lượng chữ cái giống nhau, nhưng theo thứ tự khác nhau. -For instance: +Ví dụ: ``` nap - pan @@ -14,15 +14,15 @@ ear - are - era cheaters - hectares - teachers ``` -Write a function `aclean(arr)` that returns an array cleaned from anagrams. +Viết một hàm `aclean(arr)` trả về một array đã được làm sạch từ đảo chữ. -For instance: +Ví dụ: ```js let arr = ["nap", "teachers", "cheaters", "PAN", "ear", "era", "hectares"]; -alert( aclean(arr) ); // "nap,teachers,ear" or "PAN,cheaters,era" +alert( aclean(arr) ); // "nap,teachers,ear" hoặc "PAN,cheaters,era" ``` -From every anagram group should remain only one word, no matter which one. +Từ mỗi nhóm đảo chữ chỉ nên còn lại một từ, bất kể đó là từ nào. 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..a12b47d41 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,19 +1,19 @@ -That's because `map.keys()` returns an iterable, but not an array. +Đó là bởi vì `map.keys()` trả về một iterable, nhưng không phải là một array. -We can convert it into an array using `Array.from`: +Chúng ta có thể chuyển đổi nó thành một array bằng cách sử dụng `Array.from`: ```js run let map = new Map(); -map.set("name", "John"); +map.set("tên", "John"); *!* let keys = Array.from(map.keys()); */!* -keys.push("more"); +keys.push("thêm"); -alert(keys); // name, more +alert(keys); // tên, thêm ``` 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..3bb30c155 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,23 +2,23 @@ importance: 5 --- -# Iterable keys +# Khóa iterable -We'd like to get an array of `map.keys()` in a variable and then apply array-specific methods to it, e.g. `.push`. +Chúng ta muốn lấy một array `map.keys()` trong một biến và sau đó áp dụng các phương thức dành riêng cho array đó, ví dụ: `.push`. -But that doesn't work: +Nhưng nó không hoạt động: ```js run let map = new Map(); -map.set("name", "John"); +map.set("tên", "John"); let keys = map.keys(); *!* // Error: keys.push is not a function -keys.push("more"); +keys.push("thêm"); */!* ``` -Why? How can we fix the code to make `keys.push` work? +Tại sao? Chúng ta có thể sửa mã để làm cho `keys.push` hoạt động bằng cách nào? 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..82b5f9110 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 và Set -Till now, we've learned about the following complex data structures: +Cho đến bây giờ, chúng ta đã học về các cấu trúc dữ liệu phức tạp sau: -- Objects are used for storing keyed collections. -- Arrays are used for storing ordered collections. +- Các đối tượng được sử dụng để lưu trữ các bộ sưu tập có khóa. +- Array được dùng để lưu trữ các tập hợp có thứ tự. -But that's not enough for real life. That's why `Map` and `Set` also exist. +Nhưng điều đó là không đủ cho cuộc sống thực. Đó là lý do tại sao `Map` và `Set` cũng tồn tại. ## 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](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) là tập hợp các mục dữ liệu có khóa, giống như một `Đối tượng`. Nhưng điểm khác biệt chính là `Map` cho phép các loại khóa bất kỳ. -Methods and properties are: +Các phương thức và thuộc tính là: -- `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()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/Map) -- tạo map. +- [`map.set(key, value)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/set) -- lưu trữ value theo key. +- [`map.get(key)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/get) -- trả về value theo key, `undefined` nếu `key` không tồn tại trong map. +- [`map.has(key)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/has) -- trả về `true` nếu `key` tồn tại, `false` nếu không. +- [`map.delete(key)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/delete) -- xóa phần tử (cặp khóa/giá trị) theo khóa. +- [`map.clear()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/clear) -- xóa mọi thứ khỏi map. +- [`map.size`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/size) -- trả về số lượng phần tử hiện tại. -For instance: +Ví dụ: ```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'); // một khóa chuỗi +map.set(1, 'num1'); // một khóa số +map.set(true, 'bool1'); // một khóa boolean -// remember the regular Object? it would convert keys to string -// Map keeps the type, so these two are different: +// nhớ Đối tượng thông thường không? nó sẽ chuyển đổi các khóa thành chuỗi +// Map giữ nguyên kiểu, vì vậy hai cái này khác nhau: 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. +Như chúng ta có thể thấy, không giống như các đối tượng, các khóa không được chuyển thành chuỗi. Bất kỳ loại khóa nào đều có thể tồn tại. -```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]` không phải là cách đúng đắn để sử dụng `Map`" +Mặc dù `map[key]` cũng hoạt động, ví dụ: chúng ta có thể đặt `map[key] = 2`, điều này đang coi `map` là một đối tượng JavaScript đơn giản, do đó, nó bao hàm tất cả các giới hạn tương ứng (chỉ các khóa chuỗi/ký hiệu, v.v.). -So we should use `map` methods: `set`, `get` and so on. +Vì vậy, chúng ta nên sử dụng các phương thức `map`: `set`, `get`, v.v. ``` -**Map can also use objects as keys.** +**Map cũng có thể sử dụng các đối tượng làm khóa.** -For instance: +Ví dụ: ```js run let john = { name: "John" }; -// for every user, let's store their visits count +// đối với mọi người dùng, hãy lưu trữ số lượt truy cập của họ let visitsCountMap = new Map(); -// john is the key for the map +// john là khóa cho 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`. +Sử dụng các đối tượng làm khóa là một trong những tính năng `Map` đáng chú ý và quan trọng nhất. Điều tương tự không được tính cho `Đối tượng`. Chuỗi làm khóa trong `Đối tượng` thì được, nhưng chúng ta không thể sử dụng `Đối tượng` khác làm khóa trong `Đối tượng`. -Let's try: +Hãy thử: ```js run let john = { name: "John" }; let ben = { name: "Ben" }; -let visitsCountObj = {}; // try to use an object +let visitsCountObj = {}; // cố gắng sử dụng một đối tượng -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; // cố gắng sử dụng đối tượng ben làm khóa +visitsCountObj[john] = 123; // cố gắng sử dụng đối tượng john làm khóa, đối tượng ben sẽ được thay thế *!* -// That's what got written! +// Đó là những gì đã được viết! 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. +Vì `visitsCountObj` là một đối tượng nên nó chuyển đổi tất cả các khóa `Object`, chẳng hạn như `john` và `ben` ở trên, thành cùng một chuỗi `"[object Object]"`. Chắc chắn không phải những gì chúng ta muốn. -```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="Cách `Map` so sánh các khóa" +Để kiểm tra tính tương đương của các khóa, `Map` sử dụng thuật toán [SameValueZero](https://tc39.github.io/ecma262/#sec-samevaluezero). Nó gần giống với đẳng thức nghiêm ngặt `===`, nhưng điểm khác biệt là `NaN` được coi là bằng `NaN`. Vì vậy, `NaN` cũng có thể được sử dụng làm khóa. -This algorithm can't be changed or customized. +Thuật toán này không thể thay đổi hoặc tùy chỉnh. ``` -````smart header="Chaining" -Every `map.set` call returns the map itself, so we can "chain" the calls: +````smart header="Xâu chuỗi" +Mỗi lệnh gọi `map.set` đều trả về chính map, vì vậy chúng ta có thể "xâu chuỗi" các lệnh gọi: ```js map.set('1', 'str1') @@ -101,58 +101,58 @@ map.set('1', 'str1') ```` -## Iteration over Map +## Lặp lại qua Map -For looping over a `map`, there are 3 methods: +Để lặp qua `map`, có 3 phương thức: -- `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()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/keys) -- trả về một iterable cho các khóa, +- [`map.values()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/values) -- trả về một iterable cho các giá trị, +- [`map.entries()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/entries) -- trả về một iterable cho các mục nhập `[key, value]`, nó được sử dụng theo mặc định trong `for..of`. -For instance: +Ví dụ: ```js run let recipeMap = new Map([ - ['cucumber', 500], - ['tomatoes', 350], - ['onion', 50] + ['dưa leo', 500], + ['cà chua', 350], + ['hành', 50] ]); -// iterate over keys (vegetables) +// lặp lại các khóa (rau) for (let vegetable of recipeMap.keys()) { - alert(vegetable); // cucumber, tomatoes, onion + alert(vegetable); // dưa leo,cà chua,hành } -// iterate over values (amounts) +// lặp lại các giá trị (số lượng) for (let amount of recipeMap.values()) { - alert(amount); // 500, 350, 50 + 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) +// lặp lại các mục [key, value] +for (let entry of recipeMap) { // giống như của RecipeMap.entries() + alert(entry); // dưa leo,500 (v.v) } ``` -```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="Thứ tự chèn được sử dụng" +Việc lặp đi lặp lại theo thứ tự như các giá trị đã được chèn vào. `Map` duy trì thứ tự này, không giống như `Đối tượng` thông thường. ``` -Besides that, `Map` has a built-in `forEach` method, similar to `Array`: +Bên cạnh đó, `Map` có phương thức `forEach` tích hợp, tương tự như `Array`: ```js -// runs the function for each (key, value) pair +// chạy hàm cho từng cặp (key, value) recipeMap.forEach( (value, key, map) => { - alert(`${key}: ${value}`); // cucumber: 500 etc + alert(`${key}: ${value}`); // dưa leo: 500 v.v }); ``` -## Object.entries: Map from Object +## Object.entries: Map từ Đối tượng -When a `Map` is created, we can pass an array (or another iterable) with key/value pairs for initialization, like this: +Khi một `Map` được tạo, chúng ta có thể truyền một array (hoặc một iterable) với các cặp khóa/giá trị để khởi tạo, như sau: ```js run -// array of [key, value] pairs +// array của các cặp [key, value] 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. +Nếu chúng ta có một đối tượng đơn giản và chúng ta muốn tạo một `Map` từ nó, thì chúng ta có thể sử dụng phương thức tích hợp [Object.entries(obj)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries) trả về một array của các cặp khóa/giá trị cho một đối tượng chính xác ở định dạng đó. -So we can create a map from an object like this: +Vì vậy, chúng ta có thể tạo map từ một đối tượng như thế này: ```js run let obj = { @@ -179,76 +179,76 @@ 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. +Ở đây, `Object.entries` trả về array các cặp khóa/giá trị: `[ ["name","John"], ["age", 30] ]`. Đó là những gì `Map` cần. -## Object.fromEntries: Object from Map +## Object.fromEntries: Đối tượng từ Map -We've just seen how to create `Map` from a plain object with `Object.entries(obj)`. +Chúng ta vừa xem cách tạo `Map` từ một đối tượng đơn giản với `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: +Có một phương thức `Object.fromEntries` thực hiện ngược lại: được cung cấp một array gồm các cặp `[key, value]`, nó tạo ra một đối tượng từ chúng: ```js run let prices = Object.fromEntries([ - ['banana', 1], - ['orange', 2], - ['meat', 4] + ['chuối', 1], + ['cam', 2], + ['thịt', 4] ]); -// now prices = { banana: 1, orange: 2, meat: 4 } +// bây giờ prices = {chuối: 1, cam: 2, thịt: 4} alert(prices.orange); // 2 ``` -We can use `Object.fromEntries` to get a plain object from `Map`. +Chúng ta có thể sử dụng `Object.fromEntries` để lấy một đối tượng đơn giản từ `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. +Ví dụ. chúng ta lưu trữ dữ liệu trong `Map`, nhưng chúng ta cần chuyển dữ liệu đó tới mã của bên thứ 3 mong đợi một đối tượng đơn giản. -Here we go: +Bắt đầu nhé: ```js run let map = new Map(); -map.set('banana', 1); -map.set('orange', 2); -map.set('meat', 4); +map.set('chuối', 1); +map.set('cam', 2); +map.set('thịt', 4); *!* -let obj = Object.fromEntries(map.entries()); // make a plain object (*) +let obj = Object.fromEntries(map.entries()); // tạo một đối tượng đơn giản (*) */!* -// done! -// obj = { banana: 1, orange: 2, meat: 4 } +// xong! +// obj = { chuối: 1, cam: 2, thịt: 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`. +Lệnh gọi `map.entries()` trả về một iterable của cặp khóa/giá trị, chính xác ở định dạng phù hợp cho `Object.fromEntries`. -We could also make line `(*)` shorter: +Chúng ta cũng có thể làm cho dòng `(*)` ngắn hơn: ```js let obj = Object.fromEntries(map); // omit .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`. +Điều đó cũng tương tự, bởi vì `Object.fromEntries` mong đợi một đối tượng iterable làm đối số. Không nhất thiết phải là một array. Và phép lặp tiêu chuẩn cho `map` trả về các cặp khóa/giá trị giống như `map.entries()`. Vì vậy, chúng ta nhận được một đối tượng đơn giản có cùng khóa/giá trị với `map`. ## Set -A `Set` is a special type collection - "set of values" (without keys), where each value may occur only once. +[`Set`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set) là một bộ sưu tập loại đặc biệt - "bộ giá trị" (không có khóa), trong đó mỗi giá trị chỉ có thể xuất hiện một lần. -Its main methods are: +Các phương pháp chính của nó là: -- `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])`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/Set) -- tạo tập hợp và nếu một đối tượng `iterable` được cung cấp (thường là một array), sao chép các giá trị từ đối tượng đó vào tập hợp. +- [`set.add(value)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/add) -- thêm một giá trị, trả về chính tập hợp đó. +- [`set.delete(value)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/delete) -- xóa giá trị, trả về `true` nếu `value` tồn tại tại thời điểm gọi, nếu không thì `false`. +- [`set.has(value)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/has) -- trả về `true` nếu giá trị tồn tại trong tập hợp, nếu không thì `false`. +- [`set.clear()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/clear) -- xóa mọi thứ khỏi tập hợp. +- [`set.size`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/size) -- là số lượng phần tử. -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. +Đặc điểm chính là các lệnh gọi lặp lại `set.add(value)` với cùng một giá trị không làm được gì cả. Đó là lý do tại sao mỗi giá trị chỉ xuất hiện trong `Set` một lần. -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. +Ví dụ: chúng ta có khách đến thăm và chúng ta muốn ghi nhớ tất cả mọi người. Nhưng các lượt truy cập lặp lại không nên dẫn đến trùng lặp. Một khách truy cập chỉ được "đếm" một lần. -`Set` is just the right thing for that: +`Set` chỉ là thứ phù hợp cho việc đó: ```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 +// lượt truy cập, một số người dùng đến nhiều lần set.add(john); set.add(pete); set.add(mary); set.add(john); set.add(mary); -// set keeps only unique values +// set chỉ giữ các giá trị duy nhất alert( set.size ); // 3 for (let user of set) { - alert(user.name); // John (then Pete and Mary) + alert(user.name); // John (sau đó Pete và 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. +Lựa chọn thay thế cho `Set` có thể là một array người dùng và mã để kiểm tra các trùng lặp trên mỗi lần chèn bằng cách sử dụng [arr.find](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find). Nhưng hiệu năng sẽ tệ hơn nhiều, bởi vì phương thức này duyệt qua toàn bộ array để kiểm tra mọi phần tử. `Set` được tối ưu hóa bên trong tốt hơn nhiều để kiểm tra tính duy nhất. -## Iteration over Set +## Lặp lại qua Set -We can loop over a set either with `for..of` or using `forEach`: +Chúng ta có thể lặp qua một set bằng `for..of` hoặc sử dụng `forEach`: ```js run let set = new Set(["oranges", "apples", "bananas"]); for (let value of set) alert(value); -// the same with forEach: +// tương tự với 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. +Lưu ý điều buồn cười này. Hàm gọi lại được truyền trong `forEach` có 3 đối số: `value`, sau đó là *giá trị giống nhau* `valueAgain`, sau đó là đối tượng đích. Thật vậy, cùng một giá trị xuất hiện trong các đối số hai lần. -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. +Đó là để tương thích với `Map` trong đó cuộc gọi lại được thông qua `forEach` có ba đối số. Trông hơi lạ, chắc chắn. Nhưng điều này có thể giúp thay thế `Map` bằng `Set` trong một số trường hợp một cách dễ dàng và ngược lại. -The same methods `Map` has for iterators are also supported: +Các phương thức tương tự mà `Map` dành cho các iterator cũng được hỗ trợ: -- `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()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/keys) -- trả về một đối tượng có thể lặp lại cho các giá trị, +- [`set.values()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/values) -- giống như `set.keys()`, để tương thích với `Map`, +- [`set.entries()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/entries) -- trả về một đối tượng có thể lặp lại cho các mục nhập `[giá trị, giá trị]`, tồn tại để tương thích với `Map`. -## Summary +## Tóm tắt -`Map` -- is a collection of keyed values. +[`Map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) -- là tập hợp các giá trị được khóa. -Methods and properties: +Các phương thức và thuộc tính: -- `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])`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/Map) -- tạo map, với `iterable` (ví dụ: array) tùy chọn của các cặp `[key,value]` để khởi tạo. +- [`map.set(key, value)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/set) -- lưu trữ value theo key, trả về chính map. +- [`map.get(key)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/get) -- trả về giá trị theo khóa, `undefined` nếu `key` không tồn tại trong map. +- [`map.has(key)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/has) -- trả về `true` nếu `key` tồn tại, `false` nếu không. +- [`map.delete(key)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/delete) -- xóa phần tử theo key, trả về `true` nếu `key` tồn tại tại thời điểm gọi, nếu không thì `false`. +- [`map.clear()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/clear) -- xóa mọi thứ khỏi map. +- [`map.size`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/size) -- trả về số phần tử hiện tại. -The differences from a regular `Object`: +Sự khác biệt so với `Đối tượng` thông thường: -- Any keys, objects can be keys. -- Additional convenient methods, the `size` property. +- Bất kỳ khóa, đối tượng nào cũng có thể là key. +- Các phương thức tiện lợi bổ sung, thuộc tính `size`. -`Set` -- is a collection of unique values. +[`Set`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set) -- là tập hợp các giá trị duy nhất. -Methods and properties: +Các phương thức và thuộc tính: -- `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])`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/Set) -- tạo set, với `iterable` tùy chọn (ví dụ: array) các giá trị để khởi tạo. +- [`set.add(value)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/add) -- thêm một value (không làm gì nếu `value` tồn tại), trả về chính set đó. +- [`set.delete(value)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/delete) -- xóa value, trả về `true` nếu `value` tồn tại tại thời điểm gọi, nếu không thì `false`. +- [`set.has(value)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/has) -- trả về `true` nếu value tồn tại trong set, nếu không thì `false`. +- [`set.clear()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/clear) -- xóa mọi thứ khỏi set. +- [`set.size`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/size) -- là số lượng phần tử. -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. +Việc lặp lại `Map` và `Set` luôn theo thứ tự chèn, vì vậy chúng ta không thể nói rằng các bộ sưu tập này không có thứ tự, nhưng chúng ta không thể sắp xếp lại các phần tử hoặc lấy trực tiếp một phần tử theo số của nó.