Map ในภาษา JavaScript

Map เป็นออบเจ็คที่เราสามารถใช้เก็บข้อมูลในรูปแบบของ Key/Value โดยที่ออบเจ็คทุกประเภทในภาษา JavaScript นั้นสามารถใช้เป็นทั้ง Key และ Value ของ Map ได้ ในบทนี้ คุณจะได้เรียนรู้การใช้งาน Map สำหรับเก็บข้อมูล และตัวอย่างการประยุกต์ใช้ Map ในการเขียนโปรแกรม นี่เป็นเนื้อหาในบทนี้

  • การประกาศและใช้งาน Map
  • การลบค่าใน Map
  • การตรวจสอบค่าใน Map
  • การวนรอบ Map
  • Map และอาเรย์

การประกาศและใช้งาน Map

Map เป็นออบเจ็คจากคลาส Map ที่ใช้สำหรับเก็บข้อมูลในรูปแบบของ Key/Value ในตัวอย่างแรกเราจะใช้ Map สำหรับเก็บข้อมูลโดยใช้ตัวเลขเป็น Key และคำอ่านของตัวเลขเป็น Value ของ Map นี่เป็นตัวอย่าง

create_map.js
let myMap = new Map();

// Add data to map
myMap.set(1, "one");
myMap.set(2, "two");
myMap.set(3, "three");

// Get data from map
console.log(myMap.get(1));
console.log(myMap.get(2));
console.log(myMap.get(3));

// Get map's size
console.log("Size:", myMap.size);

นี่เป็นผลลัพธ์การทำงานของโปรแกรม

one
two
three
Size: 3

ในตัวอย่าง เป็นการแสดงการใช้งานพื้นฐานของ Map สำหรับเก็บข้อมูลในรูปแบบของ Key/Value โดยการใช้ตัวเลขเป็น Key และ String ที่เป็นคำอ่านเป็น Value ของ Map

let myMap = new Map();

ในตอนแรกเป็นการสร้างออบเจ็คจากคลาส Map เมื่อออบเจ็คถูกสร้าง เราสามารถดำเนินการต่างๆ กับ Map โดยการเรียกใช้เมธอดบนออบเจ็คได้ เช่น การเพิ่ม การตรวจสอบ หรือการลบข้อมูล เป็นต้น

myMap.set(1, "one");
myMap.set(2, "two");
myMap.set(3, "three");

เพื่อเพิ่มข้อมูลเข้าไปยัง Map เราใช้เมธอด set พารามิเตอร์แรกของเมธอดนั้นเป็น Key และพารามิเตอร์ที่สองเป็น Value ที่เราต้องการเก็บคู่กับ Key นี้

console.log(myMap.get(1));
console.log(myMap.get(2));
console.log(myMap.get(3));

เพื่ออ่านข้อมูลจาก Map เราสามารถเมธอด get เมธอดนี้ส่งค่ากลับเป็น Value ที่สอดคล้องกับ Key ดังกล่าว และในกรณีที่ไม่พบ Key ที่ต้องการรับค่าจากภายใน Map เมธอดส่งค่ากลับเป็น undefined

console.log("Size:", myMap.size);

เราสามารถตรวจสอบขนาดของข้อมูลที่ถูกเก็บใน Map ได้ด้วยการอ่านค่าจาก Property size มันส่งค่ากลับเป็นจำนวนของข้อมูลทั้งหมดที่ถูกเก็บภายใน Map โดยนับจากจำนวน Key เป็นหลัก

เราสามารถใช้เมธอด console.log เพื่อดูข้อมูลทั้งหมดใน Map ได้เหมือนกับออบเจ็คประเภทอื่นๆ ซึ่งนี่มีประโยชน์และมักใช้ในการ Debug โปรแกรม ยกตัวอย่างเช่น

print_map_object.js
let myMap = new Map();
myMap.set(1, "one");
myMap.set(2, "two");
myMap.set(3, "three");

let scores = new Map();
scores.set("metin", 30);
scores.set("chris", 40);
scores.set("gary", 50);

console.log(myMap);
console.log(scores);

นี่เป็นผลลัพธ์การทำงานของโปรแกรม

Map(3) { 1 => 'one', 2 => 'two', 3 => 'three' }
Map(3) { 'metin' => 30, 'chris' => 40, 'gary' => 50 }

ในตัวอย่างนี้ เราได้สร้างและเก็บข้อมูลภายใน Map จากนั้นใช้เมธอด console.log เพื่อเรียกดูค่าทั้งหมดที่ถูกเก็บภายใน Map ซึ่งนี่จะเป็นการแสดงทั้งขนาดและข้อมูลที่เก็บใน Map ในรูปแบบของ Key/Value

การลบค่าใน Map

เมื่อค่าถูกเก็บเข้าไปใน Map แล้ว เราสามารถลบค่าออกจาก Map โดย Key ของมันด้วยเมธอด delete นี่เป็นตัวอย่างการลบข้อมูลออกจากออบเจ็ค Map ในภาษา JavaScript

delete_from_map.js
let colors = new Map();
colors.set("red", "#ff0000");
colors.set("green", "#008000");
colors.set("blue", "#0000ff");
console.log(colors);

// Delete data from map
colors.delete("blue");
console.log(colors);

// Check for deletion
console.log(colors.has("blue"));
console.log(colors.get("blue"));

// Delete all values
colors.clear();
console.log(colors);

นี่เป็นผลลัพธ์การทำงานของโปรแกรม

Map(3) {
  'red' => '#ff0000',
  'green' => '#008000',
  'blue' => '#0000ff'
}
Map(2) { 'red' => '#ff0000', 'green' => '#008000' }
false
undefined
Map(0) {}

ในตัวอย่าง เราได้ประกาศออบเจ็ค Map สำหรับเก็บค่ารหัสของสี โดยใช้ชื่อของสีเป็น Key ของ Map และเราเพิ่มสามสีเข้าไปใน Map ด้วยเมธอด set

colors.delete("blue");

จากนั้นเราใช้เมธอด delete ในการลบค่าสีออกจาก Map เมธอดรับพารามิเตอร์เป็น Key ของค่าที่ต้องการลบออกจาก Map

console.log(colors.has("blue"));
console.log(colors.get("blue"));

เมื่อข้อมูลถูกลบออกจาก Map แล้วการเรียกใช้เมธอด has หลังจากนั้นจะส่งค่ากลับเป็น false เมธอดนี้ใช้สำหรับตรวจสอบว่ามี Key ที่ระบุเก็บค่าภายใน Map หรือไม่ และเมื่อใช้เมธอด get เพื่อรับค่าเอาค่าจาก Key ดังกล่าว เราได้รับ undefined

colors.clear();

เพื่อลบค่าทั้งหมดออกจาก Map เราสามารถใช้เมธอด clear เมธอดนี้ลบทุก Key และ Value ออกจาก Map และการอ่านค่า Property colors.size หลังจากนั้นจะส่งค่ากลับเป็น 0

การตรวจสอบค่าใน Map

เมื่อเก็บค่าบางอย่างภายใน Map แล้วเราสามารถตรวจสอบว่า Key นั้นใช้เก็บค่าไปแล้วหรือยังด้วยเมธอด has นี่เป็นตัวอย่าง

check_values.js
let days = new Map();

days.set("sunday", 1);
days.set("monday", 2);
days.set("tuesday", 3);

console.log(days.has("sunday"));    // true
console.log(days.has("friday"));    // false

ในตัวอย่างเป็นการใช้เมธอด has เพื่อตรวจสอบว่า Key ที่ระบุถูกเก็บค่าใน Map แล้วหรือไม่ เมธอดส่งค่ากลับเป็น true ถ้าหาก Key ดังกล่าวใช้เก็บค่าแล้ว และ false ถ้าหากยังไม่ถูกเก็บ นี่เป็นวิธีสำหรับตรวจสอบการมีอยู่ของ Key ใน Map

ในการใช้งานเมธอดนี้เราสามารถเขียนโปรแกรมเพื่อประยุกต์ใช้ Map ในการแก้ปัญหาต่างๆ ได้ ในตัวอย่างนี้เป็นการนับจำนวนเกรดของนักเรียน 8 คน ว่าแต่ละเกรดนั้นมีนักเรียนได้เป็นจำนวนเท่าไหร่ โดยการใช้ชื่อของเกรดเป็น Key และจำนวนของนักเรียนที่ได้เกรดดังกล่าวเป็น Value ของ Map

count_grade.js
let count = new Map();

let grades = ["B", "A", "C", "B", "C", "A", "D", "A"];

for (let item of grades) {
    if (count.has(item)) {
        count.set(item, count.get(item) + 1)
    } else {
        count.set(item, 1);
    }
}

console.log(count);

นี่เป็นผลลัพธ์การทำงานของโปรแกรม

Map(4) { 'B' => 2, 'A' => 3, 'C' => 2, 'D' => 1 }

เรามีเกรดของนักเรียนทั้งหมดเก็บในตัวแปรอาเรย์ grades จากนั้นประกาศตัวแปร count ซึ่งเป็นออบเจ็ค Map ที่ใช้สำหรับนับเกรดทั้งหมดในอาเรย์ โดยใช้ชื่อของเกรดเป็น Key ของ Map เพื่อเริ่มต้นการนับเราวนรอบค่าทั้งหมดในอาเรย์ด้วยคำสั่ง for of

if (count.has(item)) {
    count.set(item, count.get(item) + 1)
} else {
    count.set(item, 1);
}

เราใช้เมธอด has เพื่อตรวจสอบว่าเกรดถูกนับหรือเก็บใน Map แล้วหรือไม่ ถ้าหากมีแล้วเพิ่มค่าสำหรับเกรดขึ้นไป 1 แต่ถ้าหากยังไม่มีเริ่มนับใหม่จาก 1

ในตอนท้ายเราจะสามารถทราบได้ว่าแต่ละเกรดนั้นมีนักเรียนจำนวนกี่คนที่ได้ เก็บในตัวแปร count โดยมีชื่อของเกรดเป็น Key และ Value เป็นจำนวนของนักเรียนทั้งหมดที่ได้เกรดดังกล่าว จะเห็นว่านักเรียนที่ได้เกรด A นั้นมีถึงสามคน ในขณะที่เกรด D นั้นมีเพียงคนเดียว

การวนรอบ Map

Map เก็บข้อมูลในรูปแบบของลำดับที่เราเพิ่มเข้าไปใน Map ด้วยเมธอด set ในการที่จะวนรอบข้อมูลใน Map นั้นสามารถทำได้หลายวิธี วิธีที่ง่ายที่สุดคือการเมธอด forEach นี่เป็นตัวอย่าง

loop_thru_map.js
let languages = new Map();

languages.set("Metin", "JavaScript");
languages.set("Billy", "TypeScript");
languages.set("Jason", "Python");
languages.set("Mark", "PHP");

languages.forEach(function (value, key) {
    console.log(key, "=>", value);
});

นี่เป็นผลลัพธ์การทำงานของโปรแกรม

Metin => JavaScript
Billy => TypeScript
Jason => Python
Mark => PHP

ในตัวอย่าง เป็นการวนค่าใน Map ด้วยเมธอด forEach เมธอดจะทำการวนค่าใน Map ตามลำดับที่มันถูกเพิ่มเข้าไป และส่ง Value และ Key ไปยังพารามิเตอร์ value และ key ในฟังก์ชัน Callback เพื่อใช้งาน ในกรณีนี้เราเพียงแสดงค่าทั้งสองออกทางหน้าจอ

วิธีที่สองคือการใช้ Iterator เมธอด มีสามเมธอดที่เราสามารถใช้สำหรับวนรอบ Map โดยการเรียกใช้เมธอดเหล่านี้มันส่งค่ากลับเป็นออบเจ็ค Iterator ที่เราสามารถใช้สำหรับวนรอบค่าใน Map นี่เป็นตัวอย่าง

map_iterator.js
let countries = new Map();

countries.set("th", "Thailand");
countries.set("uk", "England");
countries.set("sg", "Singapore");
countries.set("de", "Germany");

// Iterate over keys
for (let key of countries.keys()) {
    console.log(key);
}

// Iterate over values
for (let key of countries.values()) {
    console.log(key);
}

// Iterate over keys/values
for (let entry of countries.entries()) {
    console.log(entry);
}

นี่เป็นผลลัพธ์การทำงานของโปรแกรม

th
uk
sg
de
Thailand
England
Singapore
Germany
[ 'th', 'Thailand' ]
[ 'uk', 'England' ]
[ 'sg', 'Singapore' ]
[ 'de', 'Germany' ]

ในตัวอย่างนี้ เป็นการใช้งานสาม Iterator เมธอดเพื่อรับเอาออบเจ็ค Iterator จากนั้นวนมันด้วยคำสั่ง for of เมธอด keys ส่งค่ากลับเป็น Iterator ของ Key เมธอด values ส่งค่ากลับเป็น Value และสุดท้ายเมธอด entries ส่งค่ากลับเป็นคู่ของ Key และ Value ภายใน Map

และอย่างที่คุณเห็น สำหรับ Iterator จากเมธอด entries ค่าที่ส่งกลับในการวนแต่ละรอบนั้นจะเป็นอาเรย์ของ Key และ Value เราสามารถเข้าถึงค่าโดยใช้อาเรย์ Index หรือรูปแบบของอาเรย์ Array destructing ดังตัวอย่างต่อไปนี้

for (let entry of countries.entries()) {
    let key = entry[0];
    let value = entry[1];
}
for (let entry of countries.entries()) {
    let [key, value] = entry;
}

ทั้งสองวิธีนั้นให้ผลลัพธ์ที่เหมือนกัน และในปัจจุบันการใช้งานในรูปแบบของ Array destructing จะเป็นที่นิยมกว่า

Map และอาเรย์

ในภาษา JavaScript เราสามารถแปลงอาเรย์เป็น Map และแปลง Map เป็นอาเรย์ได้ สิ่งหนึ่งที่เหมือนกันระหว่างออบเจ็คทั้งสองก็คือลำดับของข้อมูลจะเป็นเหมือนเดิมเสมอเหมือนกับตอนที่มันถูกเพิ่มเข้าไปในอาเรย์หรือ Map

เพื่อแปลงอาเรย์เป็น Map เราสามารถเตรียมข้อมูลในรูปแบบอาเรย์ของอาเรย์ [key, value] นั่นหมายความว่าเราสามารถสร้าง Map จากอาเรย์ได้ นี่ตัวอย่าง

array_to_map.js
let array = [
    ["one", 1],
    ["two", 2],
    ["three", 3]
];

let myMap = new Map(array);
console.log(myMap);

นี่เป็นผลลัพธ์การทำงานของโปรแกรม

Map(3) { 'one' => 1, 'two' => 2, 'three' => 3 }

ในตัวอย่าง เรามีอาเรย์ของอาเรย์ของตัวเลขโดยใช้ชื่อของตัวเลขเป็น Key และค่าของตัวเลขเป็น Value เราสามารถส่งอาเรย์นี้ให้กับคอนสตรัคเตอร์ของคลาส Map ในตอนสร้างออบเจ็ค ซึ่งค่าเหล่านี้จะถูกใช้เป็นค่าเริ่มต้นของ Map

ในทางกลับกัน ถ้าหากเรามีออบเจ็ค Map เราสามารถแปลงมันเป็นอาเรย์ได้ วิธีที่ง่ายที่สุดในการทำเช่นนี้ก็คือการใช้งานเมธอด Array.from นี่เป็นตัวอย่าง

map_to_array.js
let myMap = new Map();

myMap.set("a", 1);
myMap.set("b", 2);
myMap.set("c", 3);

let array = Array.from(myMap);
console.log(array);

นี่เป็นผลลัพธ์การทำงานของโปรแกรม

[ [ 'a', 1 ], [ 'b', 2 ], [ 'c', 3 ] ]

นี่เป็นการทำกลับจากตัวอย่างก่อนหน้า ในการใช้เมธอด Array.from เราสามารถแปลง Map เป็นอาเรย์ของ [key, value] เหมือนกับตอนที่ใช้สร้าง Map ได้

ในบทนี้ คุณได้เรียนรู้เกี่ยวกับ Map ออบเจ็คในภาษา JavaScript; Map นั้นเป็นออบเจ็คที่เราสามารถใช้สำหรับเก็บข้อมูลในรูปแบบของ Key/Value โดยที่ออบเจ็คทุกประเภทนั้นสามารถใช้เป็นได้ทั้ง Key และ Value ของ Map