φυβλαςのβλογ
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
蒙古语
语言学
maya
概率论
与日本相关的日记
与中国相关的日记
-- 与北京相关的日记
-- 与香港相关的日记
-- 与澳门相关的日记
与台湾相关的日记
与北欧相关的日记
与其他国家相关的日记
qiita
其他日志

按类别分日志



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

  查看日志

  推荐日志

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