Table of contents
Intro
บทความนี้จะเป็นการอธิบายความแตกต่างระหว่าง Map Filter Find Reduce Foreach Every Some ของ JavaScript ซึ่งจากช่วงที่หัด JS ใหม่ ๆ ช่วงแรก ๆ ก็จะ งง ๆ อยู่ว่าแต่ละตัวควรใช้ตอนไหน ? ทำไมบางตัวให้ผลลัพธ์ใกล้เคียงกัน ? มันแตกต่างกันอย่างไร ? คำถามเยอะไปหมด
พอหาอ่านบทความส่วนใหญ่จะพูดถึงแค่ แต่ละตัวคืออะไร ทำงานอย่างไร แต่ไม่ได้ตอบโจทย์ที่ผมต้องการรู้ถึงความแตกต่างในแต่ละตัว ดังนั้นบทความนี้จะก็จะพูดถึงสิ่งเหล่านี้และยกตัวอย่างกรณีใดที่ควรใช้
Map
Map คือเมธอดสำหรับ สร้างอาร์เร ย์ใหม่ ที่เติมด้วยผลลัพธ์ของทุกค่า
จากอาร์เรย์ที่ใช้เรียก
map((element, index, array) => { ... } )
() => { const data = [1, 2, 3, 4] const newArray = data.map( (value, key) => value > 2 && <p>key: {key}, value: {value * 2}</p> ) return newArray }
Filter
Filter คือเมธอดสำหรับ สร้างอาร์เรย์ใหม่ เมื่อผ่านเงื่อนไขที่กำหนด
จากอาร์เรย์ที่ใช้เรียก
filter((element, index, array) => { ... } )
() => { const data = [1, 2, 3, 4] const newArray = data.filter( (value, key) => value > 2 ) return JSON.stringify(newArray) }
Find
Find คือเมธอดที่จะ Return ค่าแรก
เมื่อผ่านเงื่อนไขที่กำหนด จากอาร์เรย์ที่ใช้เรียก
find((element, index, array) => { ... } )
() => { const data = [1, 2, 3, 4] const newArray = data.find( (value, key) => value > 2 ) return newArray }
Reduce
Reduce คือเมธอดสำหรับการดำเนินการ Reducer function ประกอบไปด้วย Accumulator (ค่าสะสม) Current Value (ค่าปัจจุบัน) Current Index (ตำแหน่งปัจจุบัน) Source Array (ที่มาของ Array) และ initialValue (ค่าเริ่มต้น) ใช้สำหรับการดำเนินการบางอย่างที่ต้องการผลค่าเดียว เช่น การบวกเลข หรือการดำเนินการบางอย่างตามเงื่อนไข โดยให้มีการเก็บค่าสะสมไว้
reduce((previousValue, currentValue, currentIndex, array) => { ... }, initialValue)
กรณีไม่ได้ระบุ initialValue (ค่าแรก) จะใช้ PreviousValue ในอาร์เรย์แทน และ currentValue จะเป็นค่าที่สองในอา ร์เรย์
ดังนั้นจากตัวอย่างด้านล่าง initialValue คือ 1 currentValue คือ 2
ดังนั้นจำนวนรอบ Loop ทำงานของ reduce จะเท่ากับ จำนวนสมาชิกในอาร์เรย์ - 1 (คือ 3 รอบ)
() => { const data = [1, 2, 3, 4] const newArray = data.reduce( (accumulator, currentValue) => accumulator + currentValue ) // 1 + 2 + 3 + 4 return newArray }
ตัวอย่างกรณีกำหนดค่า initialValue
() => { const initialValue = 10 const data = [1, 2, 3, 4] const newArray = data.reduce( ((accumulator, currentValue) => accumulator + currentValue), initialValue ) // (10) + 1 + 2 + 3 + 4 return newArray }
() => { const data = [[0, 1], [2, 3], [4, 5]] const newArray = data.reduce( (accumulator, currentValue) => accumulator.concat(currentValue) ) return JSON.stringify(newArray) }
สมมุติเจอโจทย์ที่ต้องนับ (Count) ค่าใน Array เฉพาะตัวที่ไม่ใช่ undefined
() => [undefined, 1, 1, undefined, undefined, 2, 5] .reduce((count, value) => (count += value !== undefined ? 1 : 0), 0)
หรือ
() => [undefined, 1, 1, undefined, undefined, 2, 5] .reduce((count, value) => (count += value !== undefined), 0)
จะเห็นว่าการนำ reduce มาใช้นั้นมีประโยชน์อย่างมากช่วยแก้ปัญหา Logic ต่าง ๆ ใช้ท่าง่ายขึ้น ซับซ้อนน้อยลง ส่วนตัวใช้บ่อยมาก 🚀
ที่จริง Reduce มีความสามารถเยอะมาก ๆ สามารถช่วยแก้ปัญหาเกี่ยวกับ Use Case บางอย่างได้หลากหลาย อาจจะต้องแยกไปเขียนเป็นบทความนึงเพื่ออธิบายเรื่องนี้
Foreach
Foreach คือเมธอดสำหรับ เรียกข้อมูลทีละตัว จากอาร์เรย์ที่ใช้เรียก หรือการ Loop นั่นเอง
forEach((element, index, array) => { ... } )
() => { const data = [1, 2, 3, 4] let total = 0 data.forEach( (value, key) => total += value + 1 ) return total }
Every
Every คือเมธอดสำหรับ ทดสอบข้อมูลทุกตัว โดยเมื่อผ่านเงื่อนไขที่กำหนด ทุกค่า
จะคืนค่า true หรือ false
every((element, index, array) => { ... } )
() => { const data = [1, 2, 3, 4] const test = data.every( (value, key) => value > 2 ) return test.toString() }
Some
Some คือเมธอดสำหรับ ทดสอบข้อมูลทุกตัว โดยเมื่อผ่านเงื่อนไขที่กำหนด แค่บางค่า
จะคืนค่า true หรือ false
some((element, index, array) => { ... } )
() => { const data = [1, 2, 3, 4] const test = data.some( (value, key) => value > 2 ) return test.toString() }