Биз азыр төмөнкү татаал маалымат структуралары жөнүндө билебиз:
- Аты аталган коллекцияларды сактоо үчүн объекттер.
- Тартиптүү коллекцияларды сактоо үчүн массивдер.
Бирок бул күнүмдүк көйгөйлөрдү чечүү үчүн дайыма эле жетиштүү боло бербейт. Map
Ошондуктан, ошондой эле бар Set
.
map
Карта - бул ачкыч/баалардын жыйнагы, Object
. Бирок негизги айырмачылык - Map
бул ар кандай түрдөгү баскычтарды колдонууга мүмкүндүк берет.
Методдору жана касиеттери:
new Map()
- коллекцияны түзөт.map.set(key, value)
–key
маанини ачкыч менен жазатvalue
.map.get(key)
– ачкычтын маанисин кайтарат жеundefined
ачкычkey
жок болсо.map.has(key)
–true
ачкычkey
коллекцияда бар болсо, кайтарат, болбосоfalse
.map.delete(key)
– элементти (ачкыч/маани жуп) баскычы менен жок кылатkey
.map.clear()
- бардык элементтердин жыйнагын тазалайт.map.size
- элементтердин учурдагы санын кайтарат.
Мисалы:
@A@let map = new Map();
map.set("1", "str1"); // строка в качестве ключа
map.set(1, "num1"); // цифра как ключ
map.set(true, "bool1"); // булево значение как ключ
// помните, обычный объект Object приводит ключи к строкам?
// Map сохраняет тип ключей, так что в этом случае сохранится 2 разных значения:
alert(map.get(1)); // "num1"
alert(map.get("1")); // "str1"
alert(map.size); // 3@A@
Көрүнүп тургандай, объекттерден айырмаланып, баскычтар саптарга ыргытылган эмес. Ачкычтар үчүн каалаган маалымат түрүн колдоно аласыз.
map[key]
бул колдонуунун туура жолу эмесMap
Ал дагы иштейт да map[key]
, мисалы, биз орното алабыз map[key] = 2
, бул учурда map
ал кадимки JavaScript объектиси катары каралат, андыктан бул бардык тиешелүү чектөөлөргө алып келет (саптар/символ ачкычтары жана башкалар).
map
Ошондуктан, биз : set
жана get
башка ыкмаларды колдонушубуз керек .
map объекттерди ачкыч катары колдоно алат.
Мисалы:
@A@let john = { name: "John" };
// давайте сохраним количество посещений для каждого пользователя
let visitsCountMap = new Map();
// объект john - это ключ для значения в объекте Map
visitsCountMap.set(john, 123);
alert(visitsCountMap.get(john)); // 123@A@
Объекттерди ачкыч катары колдонуу эң көрүнүктүү жана маанилүү өзгөчөлүктөрүнүн бири Map
. Бул мүмкүн эмес нерсе Object
. Ачкыч катары сап Object
жакшы, бирок биз Object
башкасын Object
.
Map
менен алмаштырууга аракет кылалы Object
:
@A@let john = { name: "John" };
let ben = { name: "Ben" };
let visitsCountObj = {}; // попробуем использовать объект
visitsCountObj[ben] = 234; // пробуем использовать объект ben в качестве ключа
visitsCountObj[john] = 123; // пробуем использовать объект john в качестве ключа, при этом объект ben будет замещён
// Вот что там было записано!
alert( visitsCountObj["[object Object]"] ); // 123@A@
visitsCountObj
Объект болгондуктан, ал жана сыяктуу Object
бардык баскычтарды бир сапка айлантат . Бул, албетте, биз каалаган нерсе эмес.john
ben
"[object Object]"
Map
ачкычтарды кантип салыштыратАчкычтарды салыштыруу үчүн объект SameValueZeroMap
алгоритмин колдонот . Бул дээрлик бирдей салыштыруу, бир гана айырмасы, ал барабар деп эсептелет . Ошентип, аны ачкыч катары да колдонсо болот.===
NaN
NaN
NaN
Бул алгоритмди алмаштыруу же өзгөртүү мүмкүн эмес.
Ар бир чалуу map.set
карта объектисин кайтарат, ошондуктан биз чалууларды бириктире алабыз:
map.set("1", "str1")
.set(1, "num1")
.set(true, "bool1");
Итерацияланган карта
Коллекцияны кайталоонун 3 ыкмасы бар Map
:
map.keys()
- баскычтар аркылуу кайталануучу объектти кайтарат,map.values()
- кайталануучу объектти маанилер боюнча кайтарат,map.entries()
– форманын жуптары боюнча кайталануучу объектти кайтарат[ключ, значение]
, бул параметр демейки боюнчаfor..of
.
Мисалы:
@A@let recipeMap = new Map([
["огурец", 500],
["помидор", 350],
["лук", 50]
]);
// перебор по ключам (овощи)
for (let vegetable of recipeMap.keys()) {
alert(vegetable); // огурец, помидор, лук
}
// перебор по значениям (числа)
for (let amount of recipeMap.values()) {
alert(amount); // 500, 350, 50
}
// перебор по элементам в формате [ключ, значение]
for (let entry of recipeMap) { // то же самое, что и recipeMap.entries()
alert(entry); // огурец,500 (и так далее)
}@A@
Кадимки объекттерден айырмаланып Object
, Map
итерация элементтер кошулган тартипте ишке ашат.
Мындан тышкары, анын камтылган массив ыкмасына окшош Map
орнотулган ыкмасы бар :forEach
Array
@A@// выполняем функцию для каждой пары (ключ, значение)
recipeMap.forEach((value, key, map) => {
alert(`${key}: ${value}`); // огурец: 500 и так далее
});@A@
Object.entries: Объекттин картасы
Түзүүдө Map
биз инициализациялоо үчүн ачкыч-маани жуптары менен массивди (же башка кайталануучу объектти) көрсөтө алабыз, мисалы:
@A@// массив пар [ключ, значение]
let map = new Map([
['1', 'str1'],
[1, 'num1'],
[true, 'bool1']
]);
alert( map.get('1') ); // str1@A@
Map
Эгерде бизде кадимки объект болсо жана биз андан түзүүнү кааласак , анда объектти кабыл алып, ал үчүн ачкыч-маани түгөйлөрүнүн массивдерин кайтарып турган Object.entries(obj) методу жардам берет. формат.
Map
Ошентип, биз бул сыяктуу кадимки объекттен түзө алабыз
@A@let obj = {
name: "John",
age: 30
};
let map = new Map(Object.entries(obj));
alert( map.get('name') ); // John@A@
Бул жерде Object.entries
ачкыч-маани жуптарынын массивдерин кайтарат: [ ["name","John"], ["age", 30] ]
. Бул сиз түзүшүңүз керек болгон нерсе Map
.
Object.fromEntries: Картадан объект
Map
Биз жөн гана колдонуп, кадимки объекттен кантип түзүүнү көрдүк Object.entries(obj)
.
Object.fromEntries
Тескерисинче бир ыкма бар : форманын жуптарынын массивине ылайык [ключ, значение]
, ал алардан объект түзөт:
@A@let prices = Object.fromEntries([
['banana', 1],
['orange', 2],
['meat', 4]
]);
// prices = { banana: 1, orange: 2, meat: 4 }
alert(prices.orange); // 2@A@
Object.fromEntries
Кадимки объектти алуу үчүн колдоно алабыз Map
.
Мисалы, бизде маалыматтар бар Map
, бирок алар кадимки объектти күткөн үчүнчү тараптын кодуна өтүшү керек.
Муну кантип жасоо керек:
@A@let map = new Map();
map.set('banana', 1);
map.set('orange', 2);
map.set('meat', 4);
let obj = Object.fromEntries(map.entries()); // создаём обычный объект (*)
// готово!
// obj = { banana: 1, orange: 2, meat: 4 }
alert(obj.orange); // 2@A@
Чалуу map.entries()
ачкыч/маани жуптарынын кайталануучу объектисин кайтарат, бул үчүн туура формат Object.fromEntries
.
Биз сапты (*)
дагы кыскараак жазсак болот:
let obj = Object.fromEntries(map); // убрать .entries()
Object.fromEntries
Бул массив эмес, аргумент катары кайталануучу объектти күткөндөй эле . Жана санап чыгуу map
жөн гана ачкыч/маани жуптарын кайтарат map.entries()
. Ошентип, акырында бизде окшош ачкычтар/баалуулуктар менен кадимки объект болот map
.
set
Объект Set
коллекциянын өзгөчө түрү: ар бир маани бир гана жолу пайда боло турган баалуулуктардын "топтому" (ачкычтары жок).
Анын негизги ыкмалары болуп төмөнкүлөр саналат:
new Set(iterable)
– түзөтSet
, жана эгерде кайталануучу объект (көбүнчө массив) аргумент катары берилген болсо, анда анын маанилерин жаңыга көчүрөтSet
.set.add(value)
- маанини кошот (эгерде ал бар болсо, анда эч нерсе кылбайт), ошол эле объектти кайтаратset
.set.delete(value)
– маанини жок кылат,true
эгерvalue
ал чалуу учурунда топтомдо болсо, кайтарат, болбосоfalse
.set.has(value)
–true
эгерде маани топтомдо бар болсо, кайтарат, болбосоfalse
.set.clear()
- бардык болгон баалуулуктарды жок кылат.set.size
топтомдогу элементтердин санын кайтарат.
Негизги "бөлүгү" set.add()
ошол эле маани менен кайра чакырганда эч нерсе болбойт, ушундан улам ар бир маани бир жолу чыгат экен.
Мисалы, биз зыяратчыларды күтүп жатабыз жана алардын тизмесин түзүшүбүз керек. Бирок кайталанма сапарлар кайталанууга алып келбеши керек. Ар бир келүүчү тизмеде бир гана жолу көрүлүшү керек.
Бул үчүн сизге көп нерсе Set
керек
@A@let set = new Set();
let john = { name: "John" };
let pete = { name: "Pete" };
let mary = { name: "Mary" };
// считаем гостей, некоторые приходят несколько раз
set.add(john);
set.add(pete);
set.add(mary);
set.add(john);
set.add(mary);
// set хранит только 3 уникальных значения
alert(set.size); // 3
for (let user of set) {
alert(user.name); // John (потом Pete и Mary)
}@A@
Топтого альтернатива болуп Set
конокторду кармоо үчүн массив жана arr.find менен мурунтан эле бар элементти текшерүү үчүн кошумча код болот . Бирок бул учурда, аткаруу начарыраак болот, анткени ал arr.find
элементтин бар-жоктугун текшерүү үчүн бүт массивден өтөт. Комплект Set
толуктоолор үчүн жакшыраак оптималдаштырылган, ал уникалдуулукту автоматтык түрдө текшерет.
Set объектинин үстүнөн кайталоо
Биз коюлган объекттин мазмунун метод менен for..of
же менен кайталай алабыз forEach
:
@A@let set = new Set(["апельсин", "яблоко", "банан"]);
for (let value of set) alert(value);
// то же самое с forEach:
set.forEach((value, valueAgain, set) => {
alert(value);
});@A@
Бир күлкүлүү нерсеге көңүл буралы. forEach
y ичиндеги функциянын Set
3 аргументи бар: value value
, анан ошол эле маани кайра valueAgain
, андан кийин гана максаттуу объект. Бул туура, маани аргументтердин тизмесинде эки жолу пайда болот.
Map
Бул кайра чалуу forEach
3 аргументи бар объект менен шайкештик үчүн . Бул бир аз кызыктай көрүнөт, бирок кээ бир учурларда ал оңой Map
менен алмаштырууга жардам берет Set
жана тескерисинче.
Set
сыяктуу орнотулган ыкмаларга ээ Map
:
set.keys()
- баалуулуктар үчүн кайталануучу объектти кайтарат,set.values()
– сыяктуу эле,set.keys()
менен артка шайкештик үчүн берилгенMap
,set.entries()
– форманын жуптары үчүн кайталануучу объектти кайтарат[значение, значение]
, менен артка шайкеш келүү үчүнMap
.
Бардыгы
Map
ачкыч-маани жуптарынын жыйындысы.
Методдору жана касиеттери:
new Map([iterable])
[ключ,значение]
- коллекцияны түзөт, инициализациялоо үчүн жуптардан кайталануучу объектти (көбүнчө массив) көрсөтө аласыз .map.set(key, value)
–key
маанини ачкыч менен жазатvalue
.map.get(key)
– ачкычтын маанисин кайтарат жеundefined
ачкычkey
жок болсо.map.has(key)
–true
ачкычkey
коллекцияда бар болсо, кайтарат, болбосоfalse
.map.delete(key)
– элементти ачкыч менен алып салатkey
.map.clear()
- бардык элементтердин жыйнагын тазалайт.map.size
- элементтердин учурдагы санын кайтарат.
Кадимки объекттен айырмачылыктары Object
:
- Бардык нерсе ачкыч болушу мүмкүн, анын ичинде объекттер.
- кошумча ыкмалары бар, мулк
size
.
Set
- уникалдуу баалуулуктардын жыйындысы, "топтом" деп аталган.
Методдору жана касиеттери:
new Set(iterable)
– түзөтSet
, сиз инициализациялоо үчүн маанилери бар кайталануучу объектти белгилей аласыз.set.add(value)
- маанини кошот (эгерде ал бар болсо, анда эч нерсе кылбайт), ошол эле объектти кайтаратset
.set.delete(value)
– маанини жок кылат,true
эгерvalue
ал чалуу учурунда топтомдо болсо, кайтарат, болбосоfalse
.set.has(value)
–true
эгерде маани топтомдо бар болсо, кайтарат, болбосоfalse
.set.clear()
- бардык болгон баалуулуктарды жок кылат.set.size
топтомдогу элементтердин санын кайтарат.
Итерация Map
жана Set
ар дайым элементтер кошулган тартипте жасалат, ошондуктан бул иретсиз жыйнактар деп айтууга болбойт, бирок элементтердин тартибин өзгөртө албайсыз же элементти анын саны боюнча түздөн-түз ала албайсыз.
Tasks
Бизде массив бар дейли arr
.
unique(arr)
Уникалдуу, кайталанбаган массив маанилеринин массивин кайтара турган функцияны түзүңүз arr
.
Мисалы:
@A@function unique(arr) {
/* ваш код */
}
let values = ["Hare", "Krishna", "Hare", "Krishna",
"Krishna", "Krishna", "Hare", "Hare", ":-O"
];
alert( unique(values) ); // Hare,Krishna,:-O@A@
PS Биз бул жерде саптарды колдонуп жатабыз, бирок баалуулуктар ар кандай болушу мүмкүн.
Set
PPS Уникалдуу баалуулуктарды сактоо үчүн колдонуңуз .
Анаграммалар - бир эле санда бирдей тамгалар бар, бирок алар башка тартипте жайгашкан сөздөр.
Мисалы:
nap - pan
ear - are - era
cheaters - hectares - teachers
aclean(arr)
Анаграммалардан ажыратылган сөздөрдүн массивин кайтаруучу функцияны жазыңыз .
Мисалы:
let arr = ["nap", "teachers", "cheaters", "PAN", "ear", "era", "hectares"];
alert( aclean(arr) ); // "nap,teachers,ear" или "PAN,cheaters,era"
Анаграммалардын ар бир тобунан кайсынысы болбосун, бир гана сөз калышы керек.
Биз өзгөрүлмө ачкычтардын массивдерин алып map.keys()
, анан алар менен иштешкибиз келет, мисалы, .push
.
Бирок чыкпайт:
@A@let map = new Map();
map.set("name", "John");
let keys = map.keys();
// Error: keys.push is not a function
// Ошибка: keys.push -- это не функция
keys.push("more");@A@
Неге? keys.push
Чалуу иштеши үчүн коддо эмнени өзгөртүү керек ?