Bagay na `Map`

Ipinaliwanag ng artikulong ito ang bagay na Map.

Ipapaliwanag namin ito hakbang-hakbang, mula sa mga pangunahing operasyon hanggang sa mga praktikal na halimbawa na makakatulong sa mga totoong sitwasyon.

YouTube Video

Bagay na Map

Ang Map ay isang koleksyon na nag-iimbak ng mga pares ng key at value. Katulad ito ng isang object, ngunit naiiba dahil anumang uri, tulad ng mga object, function, o primitive, ay maaaring gamitin bilang mga key, at ang pagkakasunud-sunod ng paglalagay ay nananatili.

Mga Batayan ng Map

Una, tingnan natin kung paano gumawa ng isang Map at magsagawa ng mga pangunahing operasyon.

Ang sumusunod na code ay isang simpleng halimbawa na lumilikha ng isang walang lamang mapa, nagdadagdag ng mga key, at kumukuha ng mga halaga.

1// Create an empty Map and add key-value pairs
2const m = new Map();
3m.set('a', 1);
4m.set('b', 2);
5
6console.log(m.get('a')); // 1
7console.log(m.size);     // 2
  • Sa code na ito, maaari kang magdagdag ng elemento gamit ang set, kumuha ng value gamit ang get, at tingnan ang bilang ng mga elemento gamit ang size.
  • Pinananatili ng Map ang pagkakasunod-sunod ng paglalagay, kaya ito ay angkop para sa mga proseso na nakadepende sa order.

Pag-uugali ng set, get, has, at delete

Narito ang mga halimbawa ng karaniwang pagbabasa, pagsusulat, pag-check ng pag-iral, at pagtanggal ng operasyon.

Sa sumusunod na code, maaari mong suriin ang mga return value at epekto ng bawat paraan.

 1// Demonstrate set, get, has, and delete
 2const m2 = new Map();
 3m2.set('x', 10);
 4console.log(m2.has('x'));  // true
 5console.log(m2.get('y'));  // undefined
 6
 7m2.delete('x');
 8console.log(m2.has('x'));  // false
 9
10// set returns the map itself, allowing method chaining
11m2.set('a', 1).set('b', 2);
12console.log(m2);  // Map { 'a' => 1, 'b' => 2 }
  • Nagbabalik ang get ng undefined kapag ang key ay wala. Ang has ay nagche-check kung umiiral ang isang key, at ang delete ay nag-aalis ng isang key.
  • Gayundin, dahil nagbabalik ang set ng mismong map, posible ang method chaining.

Anumang uri ay maaaring gamitin bilang key (paggamit ng object bilang key)

Isa sa mga pangunahing benepisyo ng Map ay maaari mong direktang gamitin ang mga object bilang mga key.

Ang sumusunod na halimbawa ay nagpapakita kung paano iuugnay ang mga value sa isang Map gamit ang mga object bilang mga key.

 1// Use objects as keys in a Map
 2const keyObj = { id: 1 };
 3const keyFunc = () => {};
 4const objMap = new Map();
 5
 6// Another object with the same content but a different reference
 7const anotherKeyObj = { id: 1 };
 8
 9objMap.set(keyObj, 'objectValue');
10objMap.set(keyFunc, 'functionValue');
11objMap.set(anotherKeyObj, 'anotherValue');
12
13console.log(objMap.get(keyObj));         // 'objectValue'
14console.log(objMap.get(keyFunc));        // 'functionValue'
15console.log(objMap.get(anotherKeyObj));  // 'anotherValue'
  • Kapag gumagamit ng mga object bilang key, mahalagang pareho ang reference nila. Kahit pareho ang nilalaman nila, ang mga object na magkaiba ang reference ay itinuturing na magkaiba at hindi magkapareho ang key.

Iterasyon (pag-uulit/looping)

Pinananatili ng Map ang pagkakasunod-sunod ng paglalagay, kaya kadalasang ginagamit ang iteration.

Sa ibaba, ipapakita namin kung paano gamitin ang for...of, forEach, at ang mga paraan na keys(), values(), at entries().

 1// Iterating a Map with for...of and forEach
 2const iterMap = new Map([['a', 1], ['b', 2], ['c', 3]]);
 3
 4// for...of over entries (default)
 5for (const [key, value] of iterMap) {
 6  console.log(key, value);
 7}
 8
 9// forEach callback
10iterMap.forEach((value, key) => {
11  console.log(key, value);
12});
13
14// keys() and values()
15console.log([...iterMap.keys()]);   // ['a','b','c']
16console.log([...iterMap.values()]); // [1,2,3]
  • Ang entries() ay nagbabalik ng array ng mga [key, value] na pares, na maaaring gawing array gamit ang spread syntax. Tandaan na ang callback ng forEach ay tumatanggap ng mga argumento ayon sa pagkakasunod na value, key.

Pagko-convert sa pagitan ng Map at Object

Maaari mong i-convert ang umiiral na object sa Map, o i-convert ang Map sa isang plain object o array.

 1// Convert between Map and Object / Array
 2const obj = { a: 1, b: 2 };
 3const mapFromObj = new Map(Object.entries(obj)); // Object -> Map
 4console.log(mapFromObj.get('a')); // 1
 5
 6const objFromMap = Object.fromEntries(mapFromObj); // Map -> Object
 7console.log(objFromMap); // { a: 1, b: 2 }
 8
 9const arrayFromMap = [...mapFromObj]; // Map -> Array of [key, value]
10console.log(arrayFromMap); // [['a',1], ['b',2]]
  • Ang paggamit ng Object.entries at Object.fromEntries ay nagpapadali ng pagko-convert. Gayunpaman, dahil ang mga key ng object ay limitado sa strings o symbols, nawawala ang mga non-string key kapag kinonvert pabalik sa object.

Praktikal na Pattern: Pagbibilang ng Dalas (Count Map)

Kapag binibilang ang dalas ng mga elemento sa isang array, mas pinapasimple ng paggamit ng Map ang proseso.

Ang sumusunod na code ay halimbawa ng paggamit ng Map para bilangin ang dalas ng mga string sa array at ayusin ang mga ito.

1// Count frequencies with Map
2const arr = ['apple','banana','apple','orange','banana','apple'];
3const freq = new Map();
4
5for (const item of arr) {
6  freq.set(item, (freq.get(item) || 0) + 1);
7}
8
9console.log([...freq.entries()]); // [['apple',3], ['banana',2], ['orange',1]]
  • Pinadadali ng paggamit ng Map ang pag-check ng pag-iral at pag-update. Magagawa rin ito gamit ang object, ngunit mas intuitive ang Map kapag arbitrary ang mga key.

Paalala tungkol sa Map at JSON.stringify (Serialization)

Hindi direktang maisa-serialize ng JSON.stringify ang Map. Kung kailangan mong i-save ang isang Map, kailangan mo muna itong i-convert.

Ipinapakita ng sumusunod na halimbawa kung paano i-convert ang Map sa array bago gawing JSON, at paano ito maibabalik.

1// Serialize and deserialize a Map
2const m3 = new Map([['x', 1], ['y', 2]]);
3const json = JSON.stringify([...m3]); // convert to array first
4console.log(json); // '[["x",1],["y",2]]'
5
6const restored = new Map(JSON.parse(json));
7console.log(restored.get('x')); // 1
  • Ang mga Map na kailangang i-save o ipadala ay dapat i-convert muna sa array bago i-serialize. Sa pag-restore, gamitin ang JSON.parse para gawing array, pagkatapos ay gawing Map ulit.

Panimula sa WeakMap at Paano Ito Gamitin

Iba ang WeakMap dahil ang mga key nito ay weakly referenced (subject sa garbage collection).

Kapaki-pakinabang ito sa paghawak ng cache o metadata gamit ang object bilang key, at awtomatikong nire-release kapag nakolekta na ang key na object.

1// WeakMap for metadata tied to object lifecycle
2const wm = new WeakMap();
3let obj = {};
4wm.set(obj, { meta: 'info' });
5console.log(wm.get(obj)); // { meta: 'info' }
6
7obj = null; // now the object can be GC'd and its entry removed from WeakMap
  • Hindi maaaring bilangin o suriin ang laki ng WeakMap, pero kapaki-pakinabang ito sa pag-iwas ng memory leak.

Buod

Ang Map ay isang magandang uri ng koleksyon na, hindi tulad ng object, ay nagpapahintulot sa kahit anong uri bilang key at nananatili ang pag-kakasunod-sunod ng paglalagay. Sa pag-unawa mula sa pangunahing operasyon hanggang sa advanced na paggamit, maaari mong pamahalaan ang data nang mas flexible at intuitive. Sa wastong paggamit ng Object at Map ayon sa sitwasyon ng paggamit, malaki ang maitutulong nito sa kalinawan at madaling intindihin ng iyong code.

Maaari mong sundan ang artikulo sa itaas gamit ang Visual Studio Code sa aming YouTube channel. Paki-check din ang aming YouTube channel.

YouTube Video