Skip to main content

ความแตกต่างระหว่าง Map Filter Find Reduce Foreach Every Some ของ JavaScript

Kongvut Sangkla

Intro

บทความนี้จะเป็นการอธิบายความแตกต่างระหว่าง Map Filter Find Reduce Foreach Every Some ของ JavaScript ซึ่งจากช่วงที่หัด JS ใหม่ ๆ ช่วงแรก ๆ ก็จะ งง ๆ อยู่ว่าแต่ละตัวควรใช้ตอนไหน ? ทำไมบางตัวให้ผลลัพธ์ใกล้เคียงกัน ? มันแตกต่างกันอย่างไร ? คำถามเยอะไปหมด

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

Map

Map คือเมธอดสำหรับ สร้างอาร์เรย์ใหม่ ที่เติมด้วยผลลัพธ์ของทุกค่า จากอาร์เรย์ที่ใช้เรียก

Syntax

map((element, index, array) => { ... } )

Live Editor
() => {
  
  const data = [1, 2, 3, 4]
  const newArray = data.map(
    (value, key) => value > 2 && <p>key: {key}, value: {value * 2}</p>
  )
  
  return newArray
}
Result
Loading...

Filter

Filter คือเมธอดสำหรับ สร้างอาร์เรย์ใหม่ เมื่อผ่านเงื่อนไขที่กำหนด จากอาร์เรย์ที่ใช้เรียก

Syntax

filter((element, index, array) => { ... } )

Live Editor
() => {
  
  const data = [1, 2, 3, 4]
  const newArray = data.filter(
    (value, key) => value > 2
  )
  
  return JSON.stringify(newArray)
}
Result
Loading...

Find

Find คือเมธอดที่จะ Return ค่าแรก เมื่อผ่านเงื่อนไขที่กำหนด จากอาร์เรย์ที่ใช้เรียก

Syntax

find((element, index, array) => { ... } )

Live Editor
() => {
  
  const data = [1, 2, 3, 4]
  const newArray = data.find(
    (value, key) => value > 2
  )
  
  return newArray
}
Result
Loading...

Reduce

Reduce คือเมธอดสำหรับการดำเนินการ Reducer function ประกอบไปด้วย Accumulator (ค่าสะสม) Current Value (ค่าปัจจุบัน) Current Index (ตำแหน่งปัจจุบัน) Source Array (ที่มาของ Array) และ initialValue (ค่าเริ่มต้น) ใช้สำหรับการดำเนินการบางอย่างที่ต้องการผลค่าเดียว เช่น การบวกเลข หรือการดำเนินการบางอย่างตามเงื่อนไข โดยให้มีการเก็บค่าสะสมไว้

Syntax

reduce((previousValue, currentValue, currentIndex, array) => { ... }, initialValue)

อย่าลืมว่า

กรณีไม่ได้ระบุ initialValue (ค่าแรก) จะใช้ PreviousValue ในอาร์เรย์แทน และ currentValue จะเป็นค่าที่สองในอาร์เรย์

ดังนั้นจากตัวอย่างด้านล่าง initialValue คือ 1 currentValue คือ 2

ดังนั้นจำนวนรอบ Loop ทำงานของ reduce จะเท่ากับ จำนวนสมาชิกในอาร์เรย์ - 1 (คือ 3 รอบ)

Live Editor
() => {
  
  const data = [1, 2, 3, 4]
  const newArray = data.reduce(
    (accumulator, currentValue) => accumulator + currentValue
  )

  // 1 + 2 + 3 + 4
  return newArray
}
Result
Loading...

ตัวอย่างกรณีกำหนดค่า initialValue

Live Editor
() => {
  
  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
}
Result
Loading...
Live Editor
() => {
  
  const data = [[0, 1], [2, 3], [4, 5]]
  const newArray = data.reduce(
    (accumulator, currentValue) => accumulator.concat(currentValue)
  )
  
  return JSON.stringify(newArray)
}
Result
Loading...

สมมุติเจอโจทย์ที่ต้องนับ (Count) ค่าใน Array เฉพาะตัวที่ไม่ใช่ undefined

Live Editor
() => [undefined, 1, 1, undefined, undefined, 2, 5]
  .reduce((count, value) => (count += value !== undefined ? 1 : 0), 0)
Result
Loading...

หรือ

Live Editor
() => [undefined, 1, 1, undefined, undefined, 2, 5]
  .reduce((count, value) => (count += value !== undefined), 0)
Result
Loading...

จะเห็นว่าการนำ reduce มาใช้นั้นมีประโยชน์อย่างมากช่วยแก้ปัญหา Logic ต่าง ๆ ใช้ท่าง่ายขึ้น ซับซ้อนน้อยลง ส่วนตัวใช้บ่อยมาก 🚀

ที่จริง Reduce มีความสามารถเยอะมาก ๆ สามารถช่วยแก้ปัญหาเกี่ยวกับ Use Case บางอย่างได้หลากหลาย อาจจะต้องแยกไปเขียนเป็นบทความนึงเพื่ออธิบายเรื่องนี้

Foreach

Foreach คือเมธอดสำหรับ เรียกข้อมูลทีละตัว จากอาร์เรย์ที่ใช้เรียก หรือการ Loop นั่นเอง

Syntax

forEach((element, index, array) => { ... } )

Live Editor
() => {
  
  const data = [1, 2, 3, 4]
  let total = 0
  data.forEach(
    (value, key) => total += value + 1
  )
  
  return total
}
Result
Loading...

Every

Every คือเมธอดสำหรับ ทดสอบข้อมูลทุกตัว โดยเมื่อผ่านเงื่อนไขที่กำหนด ทุกค่า จะคืนค่า true หรือ false

Syntax

every((element, index, array) => { ... } )

Live Editor
() => {
  
  const data = [1, 2, 3, 4]
  const test = data.every(
    (value, key) => value > 2
  )
  
  return test.toString()
}
Result
Loading...

Some

Some คือเมธอดสำหรับ ทดสอบข้อมูลทุกตัว โดยเมื่อผ่านเงื่อนไขที่กำหนด แค่บางค่า จะคืนค่า true หรือ false

Syntax

some((element, index, array) => { ... } )

Live Editor
() => {

  const data = [1, 2, 3, 4]
  const test = data.some(
    (value, key) => value > 2
  )

  return test.toString()
}
Result
Loading...

สรุปสั้น ๆ

MethodArrayReturn valueTotalRound
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 หรือ false14
Some คือ การทดสอบข้อมูลทุกตัว โดยเมื่อผ่านเงื่อนไขที่กำหนด แค่บางค่า[1, 2, 3, 4]true หรือ false14

อื่น ๆ

ยังมี Loop ประเภทอื่น ๆ อีกดังนี้ครับ ทำความรู้จัก Loop ประเภท for...in และ for...of การใช้งานและความแตกต่างใน JavaScript

References

Loading...