From 68be9023cd90740f89ce6b3dedf9dd157ef7f385 Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Tue, 7 Mar 2023 10:40:56 +0700 Subject: [PATCH 01/16] Update article.md --- 1-js/05-data-types/07-map-set/article.md | 262 +++++++++++------------ 1 file changed, 131 insertions(+), 131 deletions(-) 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..7a238ddf5 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](mdn:js/Map) là tập hợp các mục dữ liệu có khóa, giống như một `Object`. 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()` -- tạo map. +- `map.set(key, value)` -- lưu trữ giá trị theo khóa. +- `map.get(key)` -- trả về giá trị theo khóa, `undefined` nếu `key` không tồn tại trong map. +- `map.has(key)` -- trả về `true` nếu `key` tồn tại, `false` nếu không. +- `map.delete(key)` -- xóa giá trị theo khóa. +- `map.clear()` -- xóa mọi thứ khỏi map. +- `map.size` -- trả về số 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ớ Object 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ể. -```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à chìa 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 `Object`. Chuỗi làm khóa trong `Object` thì được, nhưng chúng ta không thể sử dụng `Object` khác làm khóa trong `Object`. -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="Dây chuyền" +Mỗi lệnh gọi `map.set` đều trả về chính bản đồ, 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 trên 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()` -- trả về một iterable cho các khóa, +- `map.values()` -- trả về một giá trị iterable, +- `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 } -// 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ư `Object` 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 chức năng cho từng cặp (khóa, giá trị) 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 array khác 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)](mdn:js/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ờ giá = {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 cặp khóa/giá trị iterable, 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` 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)` -- 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)` -- thêm một giá trị, trả về chính tập hợp đó. +- `set.delete(value)` -- 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)` -- trả về `true` nếu giá trị tồn tại trong tập hợp, nếu không thì `false`. +- `set.clear()` -- xóa mọi thứ khỏi tập hợp. +- `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 iterable 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 bản trùng lặp trên mỗi lần chèn bằng cách sử dụng [arr.find](mdn:js/Array/find). Nhưng hiệu suất 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ố. Chắc chắn nó sẽ trông hơi lạ. Nhưng 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()` -- trả về một đối tượng iterable cho các giá trị, +- `set.values()` -- giống như `set.keys()`, để tương thích với `Map`, +- `set.entries()` -- trả về một đối tượng iterable 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` -- 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])` -- 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)` -- lưu trữ giá trị theo khóa, trả về chính map. +- `map.get(key)` -- trả về giá trị theo khóa, `undefined` nếu `key` không tồn tại trong map. +- `map.has(key)` -- trả về `true` nếu `key` tồn tại, `false` nếu không. +- `map.delete(key)` -- xóa giá trị theo khóa, 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()` -- xóa mọi thứ khỏi bản map. +- `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 `Object` thông thường: -- Any keys, objects can be keys. -- Additional convenient methods, the `size` property. +- Bất kỳ chìa khóa, đồ vật nào cũng có thể là khóa. +- 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` -- 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])` -- tạo tập hợp, với `iterable` tùy chọn (ví dụ: array) các giá trị để khởi tạo. +- `set.add(value)` -- thêm một giá trị (không làm gì nếu `value` tồn tại), trả về chính set đó. +- `set.delete(value)` -- 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)` -- trả về `true` nếu giá trị tồn tại trong set, nếu không thì `false`. +- `set.clear()` -- xóa mọi thứ khỏi set. +- `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ó. From b62d338b4ff404f550ca54dcf4270733aa205f91 Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Tue, 7 Mar 2023 10:42:41 +0700 Subject: [PATCH 02/16] Update task.md --- .../07-map-set/01-array-unique-map/task.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 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 d68030032..e2d5c844f 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 thành viên 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. From e2ce85b506f56ae147235aef9427be44dc38a8d9 Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Tue, 7 Mar 2023 10:43:52 +0700 Subject: [PATCH 03/16] Update task.md --- .../07-map-set/02-filter-anagrams/task.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) 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..2f05c9530 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ữ cái -[Anagrams](https://en.wikipedia.org/wiki/Anagram) are words that have the same number of same letters, but in different order. +[Đảo ngữ](https://en.wikipedia.org/wiki/Anagram) 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,9 +14,9 @@ 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ữ cái. -For instance: +Ví dụ: ```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. +Từ mỗi nhóm đảo chữ chỉ nên còn lại một từ, bất kể đó là từ nào. From 1bf2a23f6020b0be110cfc5a1658ccb5aa3c9adf Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Tue, 7 Mar 2023 10:47:10 +0700 Subject: [PATCH 04/16] Update solution.md --- .../07-map-set/02-filter-anagrams/solution.md | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) 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..07ae743b9 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ữ cái, 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 ngữ đề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ữ cái 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ữ cái, 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 bản đồ. Vì vậy, chúng tôi 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) { From 0a5ae7468e182feeedf2f388f7a4eb1c4526d097 Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Tue, 7 Mar 2023 10:48:39 +0700 Subject: [PATCH 05/16] Update task.md --- 1-js/05-data-types/07-map-set/03-iterable-keys/task.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 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 81507647f..f57b3c9f4 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 +# 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(); @@ -16,9 +16,9 @@ map.set("name", "John"); let keys = map.keys(); *!* -// Error: keys.push is not a function +// Error: keys.push không phải một hàm keys.push("more"); */!* ``` -Why? How can we fix the code to make `keys.push` work? +Tại sao? Làm cách nào mà chúng ta có thể sửa mã để làm cho `keys.push` hoạt động? From f4e38ef36e8aec9fc2b7e34dcde1bb1450ebf627 Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Tue, 7 Mar 2023 10:49:23 +0700 Subject: [PATCH 06/16] Update solution.md --- 1-js/05-data-types/07-map-set/03-iterable-keys/solution.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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..f10060897 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. +Đó là bởi vì `map.keys()` trả về một giá trị 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 From 0a660b87a037db3cba3a538ea14dfcd4dc5116b9 Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Tue, 7 Mar 2023 20:18:14 +0700 Subject: [PATCH 07/16] Update article.md --- 1-js/05-data-types/07-map-set/article.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) 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 7a238ddf5..7d163ba3e 100644 --- a/1-js/05-data-types/07-map-set/article.md +++ b/1-js/05-data-types/07-map-set/article.md @@ -106,7 +106,7 @@ map.set('1', 'str1') Để lặp qua `map`, có 3 phương thức: - `map.keys()` -- trả về một iterable cho các khóa, -- `map.values()` -- trả về một giá trị iterable, +- `map.values()` -- trả về một giá trị có thể lặp lại, - `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`. Ví dụ: @@ -149,7 +149,7 @@ recipeMap.forEach( (value, key, map) => { ## Object.entries: Map từ Đối tượng -Khi một `Map` được tạo, chúng ta có thể truyền một array (hoặc một array khác iterable) với các cặp khóa/giá trị để khởi tạo, như sau: +Khi một `Map` được tạo, chúng ta có thể truyền một array (hoặc một array khác có thể lặp lại) với các cặp khóa/giá trị để khởi tạo, như sau: ```js run // array của các cặp [key, value] @@ -222,14 +222,14 @@ let obj = Object.fromEntries(map.entries()); // tạo một đối tượng đơ alert(obj.orange); // 2 ``` -Lệnh gọi `map.entries()` trả về một cặp khóa/giá trị iterable, chính xác ở định dạng phù hợp cho `Object.fromEntries`. +Lệnh gọi `map.entries()` trả về một cặp khóa/giá trị có thể lặp lại, chính xác ở định dạng phù hợp cho `Object.fromEntries`. Chúng ta cũng có thể làm cho dòng `(*)` ngắn hơn: ```js let obj = Object.fromEntries(map); // omit .entries() ``` -Đ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`. +Điều đó cũng tương tự, bởi vì `Object.fromEntries` mong đợi một đối tượng có thể lặp lại 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 @@ -237,7 +237,7 @@ let obj = Object.fromEntries(map); // omit .entries() Các phương pháp chính của nó là: -- `new Set(iterable)` -- 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. +- `new Set(iterable)` -- tạo tập hợp và nếu một đối tượng `có thể lặp lại` đượ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)` -- thêm một giá trị, trả về chính tập hợp đó. - `set.delete(value)` -- 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)` -- trả về `true` nếu giá trị tồn tại trong tập hợp, nếu không thì `false`. @@ -295,9 +295,9 @@ Lưu ý điều buồn cười này. Hàm gọi lại được truyền trong `f Các phương thức tương tự mà `Map` dành cho các iterator cũng được hỗ trợ: -- `set.keys()` -- trả về một đối tượng iterable cho các giá trị, +- `set.keys()` -- trả về một đối tượng có thể lặp lại cho các giá trị, - `set.values()` -- giống như `set.keys()`, để tương thích với `Map`, -- `set.entries()` -- trả về một đối tượng iterable cho các mục nhập `[giá trị, giá trị]`, tồn tại để tương thích với `Map`. +- `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`. ## Tóm tắt From 6fe9a1154276425d3fd11f4fbda9831d76832ecf Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Tue, 7 Mar 2023 20:18:52 +0700 Subject: [PATCH 08/16] Update task.md --- 1-js/05-data-types/07-map-set/01-array-unique-map/task.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 e2d5c844f..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,7 +2,7 @@ importance: 5 --- -# Lọc các thành viên array duy nhất +# Lọc các phần tử array duy nhất Đặt `arr` là một array. From da13d18c1ee132366243e7c76493b1928a59caa3 Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Tue, 7 Mar 2023 20:19:31 +0700 Subject: [PATCH 09/16] Update solution.md --- 1-js/05-data-types/07-map-set/03-iterable-keys/solution.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 f10060897..f16cf0e90 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,5 +1,5 @@ -Đó là bởi vì `map.keys()` trả về một giá trị iterable, nhưng không phải là một array. +Đó là bởi vì `map.keys()` trả về một giá trị có thể lặp lại, nhưng không phải là một array. Chúng ta có thể chuyển đổi nó thành một array bằng cách sử dụng `Array.from`: From 6d56450154a6625a8334dd480b6a9cb5a39abbf4 Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Tue, 13 Jun 2023 06:46:07 +0700 Subject: [PATCH 10/16] Update solution.md --- 1-js/05-data-types/07-map-set/02-filter-anagrams/solution.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 07ae743b9..c47e5f1f3 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 @@ -51,7 +51,7 @@ Dòng tiếp theo đưa từ vào map: map.set(sorted, word); ``` -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 bản đồ. Vì vậy, chúng tôi sẽ luôn có tối đa một từ cho mỗi mẫu dạng ký tự. +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ự. 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. From a227b139ecb8ba191c496aabca9acb8c85452791 Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Tue, 13 Jun 2023 06:47:47 +0700 Subject: [PATCH 11/16] Update task.md --- 1-js/05-data-types/07-map-set/02-filter-anagrams/task.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) 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 2f05c9530..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,9 +2,9 @@ importance: 4 --- -# Lọc đảo chữ cái +# Lọc đảo chữ -[Đảo ngữ](https://en.wikipedia.org/wiki/Anagram) là những từ có cùng số lượng chữ cái giống nhau, nhưng theo thứ tự khác nhau. +[Đả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. Ví dụ: @@ -14,14 +14,14 @@ ear - are - era cheaters - hectares - teachers ``` -Viết một hàm `aclean(arr)` trả về một array đã được làm sạch từ đảo chữ cái. +Viết một hàm `aclean(arr)` trả về một array đã được làm sạch từ đảo chữ. 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" ``` Từ mỗi nhóm đảo chữ chỉ nên còn lại một từ, bất kể đó là từ nào. From e83831f1b888020e09c4cf2c25898c55f724fd19 Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Tue, 13 Jun 2023 06:48:39 +0700 Subject: [PATCH 12/16] Update solution.md --- .../05-data-types/07-map-set/02-filter-anagrams/solution.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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 c47e5f1f3..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,4 +1,4 @@ -Để tìm tất cả các đảo chữ cái, 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 ngữ đều giống nhau. +Để 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. Ví dụ: @@ -9,14 +9,14 @@ cheaters, hectares, teachers -> aceehrst ... ``` -Chúng ta sẽ sử dụng các biến thể được sắp xếp theo chữ cái làm khóa map để chỉ lưu trữ một giá trị cho mỗi khóa: +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) { - // tách từ bằng các chữ cái, sắp xếp chúng và nối lại + // 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(''); // (*) */!* From feb5ca87b39ddf08e8efb2e83bc6ed7b330327af Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Tue, 13 Jun 2023 06:49:51 +0700 Subject: [PATCH 13/16] Update solution.md --- .../05-data-types/07-map-set/03-iterable-keys/solution.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) 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 f16cf0e90..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,5 +1,5 @@ -Đó là bởi vì `map.keys()` trả về một giá trị có thể lặp lại, nhưng không phải là một array. +Đó là bởi vì `map.keys()` trả về một iterable, nhưng không phải là một array. Chúng ta có thể chuyển đổi nó thành một array bằng cách sử dụng `Array.from`: @@ -7,13 +7,13 @@ Chúng ta có thể chuyển đổi nó thành một array bằng cách sử d ```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 ``` From a47757334b274548a1049bc3237a18b0a359d228 Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Tue, 13 Jun 2023 06:52:16 +0700 Subject: [PATCH 14/16] Update task.md --- 1-js/05-data-types/07-map-set/03-iterable-keys/task.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 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 f57b3c9f4..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 @@ -11,14 +11,14 @@ 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 không phải một hàm -keys.push("more"); +// Error: keys.push is not a function +keys.push("thêm"); */!* ``` -Tại sao? Làm cách nào mà chúng ta có thể sửa mã để làm cho `keys.push` hoạt động? +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? From 6fd208216b4e81fa42370c1aa4c03ddfa38c5695 Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Tue, 13 Jun 2023 07:09:12 +0700 Subject: [PATCH 15/16] some fixes --- 1-js/05-data-types/07-map-set/article.md | 62 ++++++++++++------------ 1 file changed, 31 insertions(+), 31 deletions(-) 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 7d163ba3e..0781fb85a 100644 --- a/1-js/05-data-types/07-map-set/article.md +++ b/1-js/05-data-types/07-map-set/article.md @@ -10,15 +10,15 @@ Nhưng điều đó là không đủ cho cuộc sống thực. Đó là lý do t ## Map -[Map](mdn:js/Map) là tập hợp các mục dữ liệu có khóa, giống như một `Object`. Nhưng điểm khác biệt chính là `Map` cho phép các loại khóa bất kỳ. +[Map](mdn:js/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ỳ. Các phương thức và thuộc tính là: - `new Map()` -- tạo map. -- `map.set(key, value)` -- lưu trữ giá trị theo khóa. -- `map.get(key)` -- trả về giá trị theo khóa, `undefined` nếu `key` không tồn tại trong map. +- `map.set(key, value)` -- lưu trữ value theo key. +- `map.get(key)` -- trả về value theo key, `undefined` nếu `key` không tồn tại trong map. - `map.has(key)` -- trả về `true` nếu `key` tồn tại, `false` nếu không. -- `map.delete(key)` -- xóa giá trị theo khóa. +- `map.delete(key)` -- xóa value theo key. - `map.clear()` -- xóa mọi thứ khỏi map. - `map.size` -- trả về số phần tử hiện tại. @@ -31,7 +31,7 @@ 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 -// nhớ Object thông thường không? nó sẽ chuyển đổi các khóa thành chuỗi +// 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' @@ -39,7 +39,7 @@ alert( map.get('1') ); // 'str1' alert( map.size ); // 3 ``` -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ể. +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]` 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.). @@ -57,13 +57,13 @@ let john = { name: "John" }; // đố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 là chìa khóa cho map +// john là khóa cho map visitsCountMap.set(john, 123); alert( visitsCountMap.get(john) ); // 123 ``` -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 `Object`. Chuỗi làm khóa trong `Object` thì được, nhưng chúng ta không thể sử dụng `Object` khác làm khóa trong `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`. Hãy thử: @@ -90,8 +90,8 @@ Vì `visitsCountObj` là một đối tượng nên nó chuyển đổi tất c Thuật toán này không thể thay đổi hoặc tùy chỉnh. ``` -````smart header="Dây chuyền" -Mỗi lệnh gọi `map.set` đều trả về chính bản đồ, vì vậy chúng ta có thể "xâu chuỗi" các lệnh gọi: +````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,12 +101,12 @@ map.set('1', 'str1') ```` -## Lặp lại trên Map +## Lặp lại qua Map Để lặp qua `map`, có 3 phương thức: - `map.keys()` -- trả về một iterable cho các khóa, -- `map.values()` -- trả về một giá trị có thể lặp lại, +- `map.values()` -- trả về một iterable cho giá trị, - `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`. Ví dụ: @@ -120,12 +120,12 @@ let recipeMap = new Map([ // lặp lại các khóa (rau) for (let vegetable of recipeMap.keys()) { - alert(vegetable); // dưa leo, cà chua, hành + alert(vegetable); // dưa leo,cà chua,hành } // 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 } // lặp lại các mục [key, value] @@ -135,13 +135,13 @@ for (let entry of recipeMap) { // giống như của RecipeMap.entries() ``` ```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ư `Object` thông thườ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. ``` Bên cạnh đó, `Map` có phương thức `forEach` tích hợp, tương tự như `Array`: ```js -// chạy chức năng cho từng cặp (khóa, giá trị) +// chạy hàm cho từng cặp (key, value) recipeMap.forEach( (value, key, map) => { alert(`${key}: ${value}`); // dưa leo: 500 v.v }); @@ -149,7 +149,7 @@ recipeMap.forEach( (value, key, map) => { ## Object.entries: Map từ Đối tượng -Khi một `Map` được tạo, chúng ta có thể truyền một array (hoặc một array khác có thể lặp lại) với các cặp khóa/giá trị để khởi tạo, như sau: +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 của các cặp [key, value] @@ -222,14 +222,14 @@ let obj = Object.fromEntries(map.entries()); // tạo một đối tượng đơ alert(obj.orange); // 2 ``` -Lệnh gọi `map.entries()` trả về một cặp khóa/giá trị có thể lặp lại, chính xác ở định dạng phù hợp cho `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`. Chúng ta cũng có thể làm cho dòng `(*)` ngắn hơn: ```js let obj = Object.fromEntries(map); // omit .entries() ``` -Điều đó cũng tương tự, bởi vì `Object.fromEntries` mong đợi một đối tượng có thể lặp lại 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`. +Đ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 @@ -237,7 +237,7 @@ let obj = Object.fromEntries(map); // omit .entries() Các phương pháp chính của nó là: -- `new Set(iterable)` -- tạo tập hợp và nếu một đối tượng `có thể lặp lại` đượ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. +- `new Set(iterable)` -- 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)` -- thêm một giá trị, trả về chính tập hợp đó. - `set.delete(value)` -- 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)` -- trả về `true` nếu giá trị tồn tại trong tập hợp, nếu không thì `false`. @@ -246,7 +246,7 @@ Các phương pháp chính của nó là: Đặ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. -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 iterable 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. +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` chỉ là thứ phù hợp cho việc đó: @@ -272,7 +272,7 @@ for (let user of set) { } ``` -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 bản trùng lặp trên mỗi lần chèn bằng cách sử dụng [arr.find](mdn:js/Array/find). Nhưng hiệu suất 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. +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](mdn:js/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. ## Lặp lại qua Set @@ -306,26 +306,26 @@ Các phương thức tương tự mà `Map` dành cho các iterator cũng đư Các phương thức và thuộc tính: - `new Map([iterable])` -- 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)` -- lưu trữ giá trị theo khóa, trả về chính map. +- `map.set(key, value)` -- lưu trữ value theo key, trả về chính map. - `map.get(key)` -- trả về giá trị theo khóa, `undefined` nếu `key` không tồn tại trong map. - `map.has(key)` -- trả về `true` nếu `key` tồn tại, `false` nếu không. -- `map.delete(key)` -- xóa giá trị theo khóa, 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()` -- xóa mọi thứ khỏi bản map. +- `map.delete(key)` -- xóa value 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()` -- xóa mọi thứ khỏi map. - `map.size` -- trả về số phần tử hiện tại. -Sự khác biệt so với `Object` thông thường: +Sự khác biệt so với `Đối tượng` thông thường: -- Bất kỳ chìa khóa, đồ vật nào cũng có thể là khóa. +- 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` -- là tập hợp các giá trị duy nhất. Các phương thức và thuộc tính: -- `new Set([iterable])` -- tạo tập hợp, với `iterable` tùy chọn (ví dụ: array) các giá trị để khởi tạo. -- `set.add(value)` -- thêm một giá trị (không làm gì nếu `value` tồn tại), trả về chính set đó. -- `set.delete(value)` -- 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)` -- trả về `true` nếu giá trị tồn tại trong set, nếu không thì `false`. +- `new Set([iterable])` -- tạo set, với `iterable` tùy chọn (ví dụ: array) các giá trị để khởi tạo. +- `set.add(value)` -- 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)` -- 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)` -- trả về `true` nếu value tồn tại trong set, nếu không thì `false`. - `set.clear()` -- xóa mọi thứ khỏi set. - `set.size` -- là số lượng phần tử. From a375fd3e51d417b82efa691737a65df4631f61a9 Mon Sep 17 00:00:00 2001 From: I_am_Vietnam <91591390+ImVietnam@users.noreply.github.com> Date: Tue, 13 Jun 2023 09:42:26 +0700 Subject: [PATCH 16/16] sync with en version and some fixes --- 1-js/05-data-types/07-map-set/article.md | 80 ++++++++++++------------ 1 file changed, 40 insertions(+), 40 deletions(-) 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 0781fb85a..82b5f9110 100644 --- a/1-js/05-data-types/07-map-set/article.md +++ b/1-js/05-data-types/07-map-set/article.md @@ -10,17 +10,17 @@ Nhưng điều đó là không đủ cho cuộc sống thực. Đó là lý do t ## Map -[Map](mdn:js/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ỳ. +[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ỳ. Các phương thức và thuộc tính là: -- `new Map()` -- tạo map. -- `map.set(key, value)` -- lưu trữ value theo key. -- `map.get(key)` -- trả về value theo key, `undefined` nếu `key` không tồn tại trong map. -- `map.has(key)` -- trả về `true` nếu `key` tồn tại, `false` nếu không. -- `map.delete(key)` -- xóa value theo key. -- `map.clear()` -- xóa mọi thứ khỏi map. -- `map.size` -- trả về số phần tử hiện tại. +- [`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. Ví dụ: @@ -105,9 +105,9 @@ map.set('1', 'str1') Để lặp qua `map`, có 3 phương thức: -- `map.keys()` -- trả về một iterable cho các khóa, -- `map.values()` -- trả về một iterable cho giá trị, -- `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`. +- [`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`. Ví dụ: @@ -162,7 +162,7 @@ let map = new Map([ alert( map.get('1') ); // str1 ``` -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)](mdn:js/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 đó. +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 đó. Vì vậy, chúng ta có thể tạo map từ một đối tượng như thế này: @@ -195,7 +195,7 @@ let prices = Object.fromEntries([ ['thịt', 4] ]); -// bây giờ giá = {chuối: 1, cam: 2, thịt: 4} +// bây giờ prices = {chuối: 1, cam: 2, thịt: 4} alert(prices.orange); // 2 ``` @@ -233,16 +233,16 @@ let obj = Object.fromEntries(map); // omit .entries() ## Set -`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. +[`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. Các phương pháp chính của nó là: -- `new Set(iterable)` -- 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)` -- thêm một giá trị, trả về chính tập hợp đó. -- `set.delete(value)` -- 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)` -- trả về `true` nếu giá trị tồn tại trong tập hợp, nếu không thì `false`. -- `set.clear()` -- xóa mọi thứ khỏi tập hợp. -- `set.size` -- là số lượng phần tử. +- [`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ử. Đặ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. @@ -272,7 +272,7 @@ for (let user of set) { } ``` -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](mdn:js/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. +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. ## Lặp lại qua Set @@ -291,42 +291,42 @@ set.forEach((value, valueAgain, set) => { 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. -Đó là để tương thích với `Map` trong đó cuộc gọi lại được thông qua `forEach` có ba đối số. Chắc chắn nó sẽ trông hơi lạ. Nhưng 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. +Đó 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. Các phương thức tương tự mà `Map` dành cho các iterator cũng được hỗ trợ: -- `set.keys()` -- trả về một đối tượng có thể lặp lại cho các giá trị, -- `set.values()` -- giống như `set.keys()`, để tương thích với `Map`, -- `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`. +- [`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`. ## Tóm tắt -`Map` -- là tập hợp các giá trị được khóa. +[`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. Các phương thức và thuộc tính: -- `new Map([iterable])` -- 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)` -- lưu trữ value theo key, trả về chính map. -- `map.get(key)` -- trả về giá trị theo khóa, `undefined` nếu `key` không tồn tại trong map. -- `map.has(key)` -- trả về `true` nếu `key` tồn tại, `false` nếu không. -- `map.delete(key)` -- xóa value 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()` -- xóa mọi thứ khỏi map. -- `map.size` -- trả về số phần tử hiện tại. +- [`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. Sự khác biệt so với `Đối tượng` thông thường: - 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` -- là tập hợp các giá trị duy nhất. +[`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. Các phương thức và thuộc tính: -- `new Set([iterable])` -- tạo set, với `iterable` tùy chọn (ví dụ: array) các giá trị để khởi tạo. -- `set.add(value)` -- 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)` -- 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)` -- trả về `true` nếu value tồn tại trong set, nếu không thì `false`. -- `set.clear()` -- xóa mọi thứ khỏi set. -- `set.size` -- là số lượng phần tử. +- [`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ử. 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ó.