ความแตกต่างระหว่าง Map Filter Find Reduce Foreach Every Some ของ JavaScript
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() }
สรุปสั้น ๆ
Method | Array | Return value | Total | Round |
---|---|---|---|---|
Map คือ การสร้างอาร์เรย์ใหม่ ด้วยผลลัพธ์ของทุกค่าจากอาร์เรย์ที่เรียกใช้ | [1, 2, 3, 4] | ได้ Array และอาจจะมีหน้าตาข้อมูล แตกต่างไปตามวิธีการ Map | ได้จำนวนเท่าเดิม หรือน้อยกว่า | 4 |
Filter คือ การสร้างอาร์เรย์ใหม่ เมื่อผ่านเงื่อนไขที่กำหนด | [1, 2, 3, 4] | ไ ด้ Array ของรูปแบบข้อมูลเดิม | ได้จำนวนเท่าเดิม หรือน้อยกว่า | 4 |
Find คือ การดำเนินการตามเงื่อนไขโดยจะ Return ค่าแรก เมื่อผ่านเงื่อนไขที่กำหนด | [1, 2, 3, 4] | ค่าเดียวของข้อมูล | 1 | หยุดเมื่อพบ |
Reduce คือ การดำเนินการบางอย่างตามเงื่อนไข และให้มีการเก็บค่าสะสมไว้ | [1, 2, 3, 4] | เป็นได้ทั้ง Array หรือ Object หรือตัวเลข โดยขึ้นอยู่กับเงื่อนไข | ค่าเดียว หรือ ขึ้นอยู่กับ Accumulator | ขึ้นอยู่กับการกำหนดค่า initialValue |
Foreach คือ การดำเนินการกับข้อมูลทีละตัว ด้วยผลลัพธ์ของทุกค่าจากอาร์เรย์ที่เรียกใช้ | [1, 2, 3, 4] | undefined | ไม่มีจำนวน | 4 |
Every คือ การทดสอบข้อมูลทุกตัว โดยเมื่อผ่านเงื่อนไขที่กำหนด ทุกค่า | [1, 2, 3, 4] | true หรือ false | 1 | 4 |
Some คือ การทดสอบข้อมูลทุกตัว โดยเมื่อผ่านเงื่อนไขที่กำหนด แค่บางค่า | [1, 2, 3, 4] | true หรือ false | 1 | 4 |
อื่น ๆ
ยังมี Loop ประเภทอื่น ๆ อีกดังนี้ครับ ทำความรู้จัก Loop ประเภท for...in และ for...of การใช้งานและความแตกต่างใน JavaScript
References
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/every
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some