φυβλαςのβλογ
บล็อกของ phyblas



javascript เบื้องต้น บทที่ ๔๖: ฟังก์ชันและเมธอดเพิ่มเติมสำหรับแถวลำดับ
เขียนเมื่อ 2020/05/11 09:18
แก้ไขล่าสุด 2021/09/28 16:42

ใน ES6 ได้มีการเพิ่มฟังก์ชันและเมธอดที่สามารถใช้กับข้อมูลชนิดแถวลำดับได้มากมายหลายตัว ในบทนี้จะมาแนะนำฟังก์ชันและเมธอดเหล่านั้น

สำหรับเมธอดที่มีมาตั้งแต่ใน ES3 ดูได้ใน บทที่ ๑๑ และ บทที่ ๑๒ ส่วนที่เพิ่มมาใน ES5 ดูใน บทที่ ๒๗




Array.from

ฟังก์ชัน Array.from() มีไว้สำหรับสร้างแถวลำดับขึ้นจากอะไรก็ได้ที่สามารถวนซ้ำได้

เช่นสร้างจาก Set หรือ Map
let mappu = new Map();
mappu.set(1, "ก");
mappu.set(2, "ข");
Array.from(mappu); // ได้แถวลำดับ [[1, 'ก'], [2, 'ข']]

let setto = new Set([3, 4, 5]);
Array.from(setto); // ได้แถวลำดับ [3, 4, 5]

หรือสร้างจากอิเทอเรเตอร์หรือเจเนอเรเตอร์ได้
function *gen(){
  yield "ข้าว";
  yield "ขนมปัง";
  yield "บะหมี่";
}
alert(Array.from(gen())); // ได้ ข้าว,ขนมปัง,บะหมี่

function* gen(arr) {
  for (let x of arr) {
    yield x ** 2;
  }
}
alert(Array.from(gen([2, 5, 7]))); // ได้ 4,25,49

ถ้าใช้กับแถวลำดับก็จะได้แถวลำดับที่หน้าตาเหมือนกันออกมา แต่ว่าเป็นตัวใหม่ ไม่ใช่ตัวเดียวกัน
let ara = ["เป็ด", "ไก่", "ห่าน"];
let arb = Array.from(ara); // ได้แถวลำดับหน้าตาเหมือนเดิมแต่ถือเป็นคนละตัว
alert(arb); // ได้ เป็ด,ไก่,ห่าน
alert(arb==ara); // ได้ false

สามารถสร้างจากออบเจ็กต์ที่มีพรอเพอร์ตีเป็นตัวเลข และมี .length อยู่ได้ โดยจะสร้างแถวลำดับที่มีความยาวตาม .length และค่าตามชื่อพรอเพอร์ตีไล่ตั้งแต่ 0, 1, 2 แต่ถ้าลำดับไหนไม่มีจะเป็น undefined
let obj1 = { 0: "ก", 2: "ค", 1: "ข", length: 3 };
let arr1 = Array.from(obj1); // เท่ากับ ["ก", "ข", "ค"]
let obj2 = { 1: "ข", 0: "ก", length: 3 };
let arr2 = Array.from(obj2); // เท่ากับ ["ก", "ข", undefined]
let obj3 = { length: 3 };
let arr3 = Array.from(obj3); // เท่ากับ [undefined, undefined, undefined]
let obj4 = {1: "ฮ", length: 4 };
let arr4 = Array.from(obj4); // เท่ากับ [undefined, "ฮ", undefined, undefined]
let obj5 = {0: "ก", 1: "ข", 1: "ค", length: 1 };
let arr5 = Array.from(obj5); // เท่ากับ ["ก"]




Array.of

ฟังก์ชัน Array.of() ใช้สร้างแถวลำดับขึ้นจากอาร์กิวเมนต์ที่มาเรียงกัน
Array() // เท่ากับ []
Array.of('5') // เท่ากับ ['5']
Array.of(2,3) // เท่ากับ [2,3]
Array.of(7) // เท่ากับ [7]

ที่จริงใช้ Array() ก็ให้ผลคล้ายกับ Array.of() คือสามารถสร้างแถวลำดับจากอาร์กิวเมนต์ได้

แต่ข้อแตกต่างก็คือ หากอาร์กิวเมนต์มีเพียงตัวเดียวและเป็นตัวเลข Array() จะเป็นการสร้างแถวลำดับเปล่าที่มีความยาวตามเลขที่ใส่
Array(5) // เท่ากับ [,,,,,]
Array.of(5) // เท่ากับ [5]

ส่วนกรณีอื่นๆจะใช้ Array.of() หรือ Array() ก็ไม่ต่างกัน
Array('5') // เท่ากับ ['5']
Array(2,3) // เท่ากับ [2,3]




.fill

เมธอด .fill() ไว้ใช้เติมข้อมูลด้วยค่าที่กำหนด

วิธีใช้
แถวลำดับ.copyWithin(ค่าที่จะเติม, ตำแหน่งที่เริ่มต้นเติม, ตำแหน่งสุดท้ายที่เติม)

หากกำหนดแค่ค่าที่จะเติม ค่านั้นก็จะถูกเติมลงไปแทนสมาชิกทั้งหมด
let ara1 = ["a", "b", "c"];
alert(ara1.fill(55)); // ได้ 55,55,55

ถ้าใส่ตำแหน่งเริ่มต้นที่เติมด้วยก็จะเติมตั้งแต่ตำแหน่งนั้นไปจนถึงท้ายสุดของแถวลำดับ
let ara2 = ["a", "b", "c", "d"];
alert(ara2.fill("ฮ", 2)); // ได้ a,b,ฮ,ฮ
let ara3 = ["e", "f", "g", "h"];
alert(ara3.fill("ฮ", 1)); // ได้ e,ฮ,ฮ,ฮ

ถ้าใส่ตำแหน่งสุดท้ายด้วยก็จะเติมไล่จากตำแหน่งเริ่มต้นไปจนถึงตำแหน่งสุดท้ายที่กำหนดนั้น
let ara4 = ["i", "j", "k", "l"];
alert(ara4.fill("อ", 1, 3)); // ได้ i,อ,อ,l
let ara5 = ["m", "n", "o", "p"];
alert(ara5.fill("อ", 0, 2)); // ได้ อ,อ,o,p

สามารถใช้คู่กับ Array() เพื่อสร้างแถวลำดับที่มีค่าเป็นตัวเดียวกันซ้ำตามจำนวนที่ต้องการ เช่น
alert(Array(7).fill("ก")) // ได้ ก,ก,ก,ก,ก,ก,ก




.copyWithin

เมธอด .copyWithin() มีไว้ทำการคัดลอกสมาชิกส่วนหนึ่งในแถวลำดับไปทับใส่ในตำแหน่งอื่น

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

วิธีใช้
แถวลำดับ.copyWithin(ตำแหน่งเป้าหมาย, ตำแหน่งที่เริ่มต้นคัดลอก, ตำแหน่งสุดท้ายที่คัดลอก)

กรณีที่ใส่แต่ตำแหน่งเป้าหมาย จะหมายถึงเป็นการคัดลอกสมาชิกจากตัวแรกไปทับตำแหน่งเป้าหมาย

ตัวอย่าง
let ar1 = ["ก", "ข", "ค", "ง", "จ"];
ar1.copyWithin(3); // กลายเป็น ก,ข,ค,ก,ข
let ar2 = ["ก", "ข", "ค", "ง", "จ"];
ar2.copyWithin(1); // กลายเป็น ก,ก,ข,ค,ง

ถ้าใส่เป็นตัวเลขติดลบจะเป็นตำแหน่งไล่จากท้ายสุดแทน
let ar3 = ["ก", "ข", "ค", "ง", "จ"];
ar3.copyWithin(-1); // กลายเป็น ก,ข,ค,ง,ก

ถ้าใส่ตำแหน่งเริ่มต้นคัดลอกไปด้วย จะเป็นการคัดลอกตัวจากตำแหน่งเริ่มต้นนั้นจนถึงตัวสุดท้ายของแถวลำดับ ไปยังตำแหน่งเป้าหมาย
let ar4 = ["ก", "ข", "ค", "ง", "จ"];
ar4.copyWithin(1,3); // กลายเป็น ก,ง,จ,ง,จ
let ar5 = ["ก", "ข", "ค", "ง", "จ"];
ar5.copyWithin(1,-1); // กลายเป็น ก,จ,ค,ง,จ
let ar6 = ["ก", "ข", "ค", "ง", "จ"];
ar6.copyWithin(0,-2); // กลายเป็น ง,จ,ค,ง,จ

ถ้าใส่ตำแหน่งสุดท้ายด้วยก็ จะเป็นการคัดลอกเอาจากตำแหน่งเริ่มต้นจนถึงตำแหน่งสุดท้ายที่กำหนดนั้น ไปยังตำแหน่งเป้าหมาย
let ar7 = ["ก", "ข", "ค", "ง", "จ"];
ar7.copyWithin(0,2,3); // กลายเป็น ค,ข,ค,ง,จ
let ar8 = ["ก", "ข", "ค", "ง", "จ"];
ar8.copyWithin(1,2,-1); // กลายเป็น ก,ค,ง,ง,จ
let ar9 = ["ก", "ข", "ค", "ง", "จ"];
ar9.copyWithin(-4,-3,-1); // กลายเป็น ก,ค,ง,ง,จ




.find

เมธอด .find() ใช้หาเอาสมาชิกที่เข้าเงื่อนไขตามฟังก์ชันที่กำหนด แล้วเอาค่าตัวนั้นมา

ฟังก์ชันที่ใช้ค้นให้ใส่เป็นฟังก์ชันที่คืนค่าออกมาเป็น true เมื่อเข้าเงื่อนไข หรือ false เมื่อไม่เข้าเงื่อนไข การค้นจะไล่จากตัวแรก และจะให้ค่าตัวแรกที่คืนค่า true ถ้าไม่เจอตัวที่เข้าเงื่อนไขเลยสักตัวจะได้ undefined


ตัวอย่าง
let ar10 = [4, 9, 3, -2, 1, -7];
alert(ar10.find(x => { return x < 0; })); // ได้ -2
let ar11 = [-3, 1, 7, -2, 3];
alert(ar11.find(x => { return x > 1; })); // ได้ 7




.findIndex

เมธอด .findIndex() จะคล้าย .find() แต่จะคืนเป็นตำแหน่งของตัวนั้นแทน และถ้าหาไม่เจอจะได้ -1

ตัวอย่าง
let ar12 = [-4, 2, -2, 9, -2, 4];
alert(ar12.findIndex(x => { return x == -2; })); // ได้ 2
let ar13 = [2, 7, 2, -5, 9, -7];
alert(ar13.findIndex(x => { return x > 6; })); // ได้ 1
let ar14 = [7, 1, -3, 5, -7];
alert(ar14.findIndex(x => { return x > 7; })); // ได้ -1




.keys, .values, .entries

เมธอด .keys(), .values() และ .entries() ใช้สำหรับไล่เรียงสมาชิกข้างในออกมาทีละตัว ใช้กับ for๛of

ในออบเจ็กต์แม็ปซึ่งเขียนถึงในบทที่ ๓๗ ก็มีเมธอดนี้ การใช้ก็เช่นเดียวกัน

.keys() จะให้ค่าคีย์ของข้อมูลแต่ละตัว ซึ่งสำหรับแถวลำดับแล้วก็คือเลขไล่ตั้งแต่ 0 จนถึงตำแหน่งสุดท้ายที่มีข้อมูล

ส่วน .values() จะไล่ค่าทีละตัว ส่วน .entries() จะให้ทั้งคีย์และค่า

ตัวอย่าง
let ari = ["ก", "ข", "ค", "ง"];

let s1 = "";
for (let x of ari.keys()) {
  s1 += x + " | ";
}
alert(s1); // ได้ 0 | 1 | 2 | 3 |

let s2 = "";
for (let x of ari.values()) {
  s2 += x + " * ";
}
alert(s2); // ได้ ก * ข * ค * ง *

let s3 = "";
for (let [k,v] of ari.entries()) {
  s3 += k + ":" + v + " ~ ";
}
alert(s3); // ได้ 0:ก ~ 1:ข ~ 2:ค ~ 3:ง ~ 




.includes [ES2016]

เมธอด .includes() ถูกเพิ่มเข้ามาใน ES2016 มีไว้ใช้หาว่าค่าที่ต้องการอยู่ในแถวลำดับนั้นหรือไม่

ตัวอย่างการใช้
aru = ["ไก่", "ไต่", "ไผ่"];
alert(aru.includes("ไก่")); // ได้ true
alert(aru.includes("ไข่")); // ได้ false
alert([null, 1, false].includes(null)); // ได้ true
alert([null, 1, false].includes("1")); // ได้ false

นอกจากนี้ยังใส่อาร์กิวเมนต์ตัวที่ ๒ เป็นตัวกำหนดว่าจะเริ่มต้นดูตั้งแต่ตำแหน่งไหน เช่น
arru = ["กา", "ชา", "มา"];
alert(arru.includes("ชา")); // ได้ true
alert(arru.includes("ชา", 1)); // ได้ true
alert(arru.includes("ชา", 2)); // ได้ false
alert(arru.includes("มา", 2)); // ได้ true

ถ้าเป็นก่อนที่จะมีเมธอดนี้เวลาที่จะหาว่ามีสมาชิกที่มีค่าที่ต้องการอยู่หรือเปล่าจะใช้ .indexOf() แทน โดยที่ถ้าคืนค่าเป็น -1 แสดงว่าไม่มี

เช่นถ้ามีสิ่งต้องการให้ทำเฉพาะเมื่อมีสมาชิกตัวนั้นอยู่ก็ ถ้าเป็นเมื่อก่อนอาจเขียนแบบนี้
if (arr.indexOf(x) !== -1) {
  // ...
}

แต่พอมี .includes() ก็สามารถเขียนแบบนี้แทน
if (arr.includes(x)) {
  // ...
}

แต่ว่ามีข้อแตกต่างบางกรณี เช่นถ้าตัวที่ต้องการหานั้นเป็น NaN แบบนี้ .indexOf() จะให้ -1 เสมอ แต่ถ้าเป็น .includes() ให้ true ถ้ามี NaN อยู่ด้วย
[NaN].indexOf(NaN) // -1
[NaN].includes(NaN) // true




.flat [ES2019]

เมธอด .flat() เพิ่มเข้ามาใน ES2019 ใช้ทำให้สมาชิกในแถวลำดับที่ซ้อนอยู่แถวลำดับถูกแจกออกมา

เมธอดนี้จะให้แถวลำดับตัวใหม่ออกมา ไม่ได้เปลี่ยนแปลงตัวแถวลำดับที่เรียกเมธอดนี้

ตัวอย่าง
let arrr = [1, [2], [3, 4]]
arrr.flat(); // กลายเป็น [1, 2, 3, 4]

แต่โดยปกติแล้วจะแจกออกมาแค่ชั้นเดียว ถ้าเป็นแถวลำดับที่ซ้อนอยู่ในแถวลำดับที่อยู่ในแถวลำดับลึกลงไปอีกมากกว่านั้นก็ต้องระบุว่าจะให้แจกลึกไปถึงกี่ชั้น และถ้าต้องการให้แจกหมดไม่ว่าจะกี่ชั้นก็อาจใส่เป็น Infinity
let arrh = [[1], [[2], [[3], 4], 5]]
arrh.flat(); // กลายเป็น [1, [2], [[3], 4], 5]
arrh.flat(2); // กลายเป็น [1, 2, [3], 4, 5]
arrh.flat(Infinity); // กลายเป็น [1, 2, 3, 4, 5]




.flatMap [ES2019]

เมธอด .flatMap() ถูกเพิ่มมาใน ES2019 พร้อมกับ .flat() มีลักษณะเหมือนใช้เมธอด .flat() คู่กับ .map()

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

ตัวอย่าง
let arb = ["กาบ", "บาด", "กบ", "ดาบ", "บก"];
function f(x) {
  return x.split("า");
}

arb.map(f); // เป็น [['ก', 'บ'], ['บ', 'ด'], ['กบ'], ['ด', 'บ'], ['บก']]
arb.map(f).flat(); // เป็น ['ก', 'บ', 'บ', 'ด', 'กบ', 'ด', 'บ', 'บก']
arb.flatMap(f); // เป็น ['ก', 'บ', 'บ', 'ด', 'กบ', 'ด', 'บ', 'บก']




สรุปเมธอดทั้งหมด

ชื่อเมธอด ความสามารถ เพิ่มมาใน
fill เติมค่าเหมือนกันใส่ให้ทุกตัวในแถวลำดับ ES2015
copyWithin คัดลอกค่าจากสมาชิกส่วนหนึ่งไปให้อีกส่วน
find ค้นหาค่าที่มีเงื่อนไขตามที่ต้องการภายในแถวลำดับ
findIndex ค้นหาตำแหน่งของตัวที่ค่าที่มีเงื่อนไขตามที่ต้องการภายในแถวลำดับ ถ้าไม่เจอจะได้ -1
keys ไล่เรียงค่าคีย์ทั้งหมดทุกตัวในแถวลำดับนี้ (ใช้กับ for๛of)
values ไล่เรียงค่าทั้งหมดทุกตัวในแถวลำดับนี้ (ใช้กับ for๛of)
entries ไล่เรียงคีย์พร้อมค่าของทุกตัวในแถวลำดับนี้ (ใช้กับ for๛of)
includes ดูว่ามีตัวที่ต้องการอยู่ในแถวลำดับหรือไม่ (ได้ true, false) ES2016
flat แจกแถวลำดับที่อยู่ภายในแถวลำดับให้เป็นสมาชิกโดยตรงในแถวลำดับนั้น ES2019
flatMap เหมือนใช้ map ตามด้วย flat







-----------------------------------------

囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧

ดูสถิติของหน้านี้

หมวดหมู่

-- คอมพิวเตอร์ >> เขียนโปรแกรม >> javascript

ไม่อนุญาตให้นำเนื้อหาของบทความไปลงที่อื่นโดยไม่ได้ขออนุญาตโดยเด็ดขาด หากต้องการนำบางส่วนไปลงสามารถทำได้โดยต้องไม่ใช่การก๊อปแปะแต่ให้เปลี่ยนคำพูดเป็นของตัวเอง หรือไม่ก็เขียนในลักษณะการยกข้อความอ้างอิง และไม่ว่ากรณีไหนก็ตาม ต้องให้เครดิตพร้อมใส่ลิงก์ของทุกบทความที่มีการใช้เนื้อหาเสมอ

สารบัญ

รวมคำแปลวลีเด็ดจากญี่ปุ่น
มอดูลต่างๆ
-- numpy
-- matplotlib

-- pandas
-- manim
-- opencv
-- pyqt
-- pytorch
การเรียนรู้ของเครื่อง
-- โครงข่าย
     ประสาทเทียม
ภาษา javascript
ภาษา mongol
ภาษาศาสตร์
maya
ความน่าจะเป็น
บันทึกในญี่ปุ่น
บันทึกในจีน
-- บันทึกในปักกิ่ง
-- บันทึกในฮ่องกง
-- บันทึกในมาเก๊า
บันทึกในไต้หวัน
บันทึกในยุโรปเหนือ
บันทึกในประเทศอื่นๆ
qiita
บทความอื่นๆ

บทความแบ่งตามหมวด



ติดตามอัปเดตของบล็อกได้ที่แฟนเพจ

  ค้นหาบทความ

  บทความแนะนำ

ตัวอักษรกรีกและเปรียบเทียบการใช้งานในภาษากรีกโบราณและกรีกสมัยใหม่
ที่มาของอักษรไทยและความเกี่ยวพันกับอักษรอื่นๆในตระกูลอักษรพราหมี
การสร้างแบบจำลองสามมิติเป็นไฟล์ .obj วิธีการอย่างง่ายที่ไม่ว่าใครก็ลองทำได้ทันที
รวมรายชื่อนักร้องเพลงกวางตุ้ง
ภาษาจีนแบ่งเป็นสำเนียงอะไรบ้าง มีความแตกต่างกันมากแค่ไหน
ทำความเข้าใจระบอบประชาธิปไตยจากประวัติศาสตร์ความเป็นมา
เรียนรู้วิธีการใช้ regular expression (regex)
การใช้ unix shell เบื้องต้น ใน linux และ mac
g ในภาษาญี่ปุ่นออกเสียง "ก" หรือ "ง" กันแน่
ทำความรู้จักกับปัญญาประดิษฐ์และการเรียนรู้ของเครื่อง
ค้นพบระบบดาวเคราะห์ ๘ ดวง เบื้องหลังความสำเร็จคือปัญญาประดิษฐ์ (AI)
หอดูดาวโบราณปักกิ่ง ตอนที่ ๑: แท่นสังเกตการณ์และสวนดอกไม้
พิพิธภัณฑ์สถาปัตยกรรมโบราณปักกิ่ง
เที่ยวเมืองตานตง ล่องเรือในน่านน้ำเกาหลีเหนือ
ตระเวนเที่ยวตามรอยฉากของอนิเมะในญี่ปุ่น
เที่ยวชมหอดูดาวที่ฐานสังเกตการณ์ซิงหลง
ทำไมจึงไม่ควรเขียนวรรณยุกต์เวลาทับศัพท์ภาษาต่างประเทศ

บทความแต่ละเดือน

2024年

1月 2月 3月 4月
5月 6月 7月 8月
9月 10月 11月 12月

2023年

1月 2月 3月 4月
5月 6月 7月 8月
9月 10月 11月 12月

2022年

1月 2月 3月 4月
5月 6月 7月 8月
9月 10月 11月 12月

2021年

1月 2月 3月 4月
5月 6月 7月 8月
9月 10月 11月 12月

2020年

1月 2月 3月 4月
5月 6月 7月 8月
9月 10月 11月 12月

ค้นบทความเก่ากว่านั้น

ไทย

日本語

中文