Cinecus CC
Published on

แชร์ JavaScript Array Method ที่ใช้บ่อย ๆ ตอนที่ 2 : map, filter, reduce

Overview

จากตอนที่แล้วเราได้รู้จักกับ Array แล้วก็วิธีการวน loop แบบต่าง ๆไปแล้ว วันนี้จะมาแชร์วิธีการวน loop array ด้วย Method ที่นิยม 3 ตัว คือ map, filter และ reduce กันครับ

Array Data

ก่อนอื่นขอสมมติข้อมูล Array ชื่อ products ขึ้นมา โดยใน Array จะประกอบด้วย object ที่มี field ดังนี้ name, price, color

index.js

const products = [
    {
        name: 'A',
        price: 10,
        color: 'red'
    },
    {
        name: 'B',
        price: 20,
        color: 'black'
    },
    {
        name: 'C',
        price: 30,
        color: 'white'
    },
    {
        name: 'D',
        price: 40,
        color: 'black'
    },
    {
        name: 'E',
        price: 50,
        color: 'white'
    }
]

map

map เป็น Array Method ที่จะทำการวน loop Array โดยข้างใน map จะเป็น function ที่ส่วนใหญ่รับ argument 2ตัว ตัวแรกเป็น element ตัวหลังจะเป็น index โดยมีการ return ค่าเสมอ และผลลัพธ์จะเป็น Array ที่มีความยาวเท่ากับ Array ตั้งต้น

array.map((element,index)=>do something)

ตัวอย่าง : สมมติว่าเรามี Array ของสินค้าแล้วอยาก check ว่าสินค้าถ้าเป็นสีขาวจะ เพิ่ม field ชื่อ is_available เท่ากับ false แต่ถ้าไม่ใช่สีขาว จะเท่ากับ true

index.js

const result = products.map((element, i) => {
    const is_available = element.color !== 'white' // ถ้าเป็นสีขาว เท่ากับ false ถ้าไม่ใช่ เท่ากับ true
    return { ...element, is_available }
})

console.log('result', result)

ผลลัพธ์

result [
  { name: 'A', price: 10, color: 'red', is_available: true },
  { name: 'B', price: 20, color: 'black', is_available: true },
  { name: 'C', price: 30, color: 'white', is_available: false },
  { name: 'D', price: 40, color: 'black', is_available: true },
  { name: 'E', price: 50, color: 'white', is_available: false }
]

filter

filter ทุกอย่างคล้าย map แต่ตรง return จะมีการ check เงื่อนไขของข้อมูลให้เหลือเฉพาะเงื่อนไขที่เป็นจริง

array.filter((element,index)=>condition filter)

ตัวอย่าง : สมมติว่าเรามี Array ของสินค้าแล้วอยากกรองให้เหลือเฉพาะสินค้าที่ราคาน้อยกว่าหรือเท่ากับ 30บาท

index.js

const result = products.filter((element, i) => {
    return element.price <= 30
})

console.log('result', result)

ผลลัพธ์

result [
  { name: 'A', price: 10, color: 'red' },
  { name: 'B', price: 20, color: 'black' },
  { name: 'C', price: 30, color: 'white' }
]

reduce

reduce เป็น Method ที่อาจจะแตกต่างกับ map และ filter ตรงที่ค่าที่ return จาก reduce จะเป็นอะไรก็ได้โดยข้างใน reduce จะมี function กับ initial accumulated (ค่าที่ถูกสะสม) และข้างใน function ส่วนใหญ่จะรับ argument 3ตัว ตัวแรกคือ previous (ค่าที่ถูกสะสมจากรอบวนลูปก่อนหน้า) ตัวสองคือ current (element ปัจจุบัน) ตัวสามคือ index (ไม่จำเป็นก็ได้)

array.reduce((previous,current)=>do something , initialValue)

ตัวอย่างแรก : สมมติว่าเรามี Array ของสินค้าแล้วอยากหาผลรวมราคาของสินค้าทั้งหมด

index.js

const result = products.reduce((prev, cur, i) => {
    return prev + cur.price
}, 0)

console.log('result', result)

ผลลัพธ์

result 150

ตัวอย่างที่ 2 : สมมติว่าเรามี Array ของสินค้าแล้วอยากนับจำนวนสินค้าแต่ละสีว่ามีกี่อัน

index.js

const result = products.reduce((prev, cur, i) => {
    return { ...prev, [cur.color]: prev[cur.color] + 1 || 1 }
}, {})

console.log('result', result)

ผลลัพธ์

result { red: 1, black: 2, white: 2 }

สังเกตว่า ค่าที่ return ออกมาเราสามารถกำหนดเองได้ ไม่จำเป็นว่าต้อง return กลับมาเป็น array

สรุปการใช้ map, filter และ reduce

  • ถ้าต้องการวนลูป array แล้วมีการทำอะไรบางอย่างกับ array โดยอยากเอา array หรือ result ไปใช้ต่อ ค่าควรมาใช้ map, filter, reduce แทนพวก for loop ทั่วไป เพื่อง่ายต่อการอ่านโค้ด
  • map ใช้สำหรับต้องการแปลงค่าหรือเพิ่ม field ใน array โดยได้จำนวน array ที่เข้าไปต้องเท่ากับ array ผลลัพธ์
  • filter ใช้สำหรับต้องการกรองเอาข้อมูลบางตัวใน array ออก
  • reduce การใช้งานค่อนข้างหลากหลาย ต้องระลึกในใจเสมอว่าอยากได้ผลลัพธ์แบบไหน ซึ่งถ้าลองใช้แรก ๆอาจจะหลง ๆ ลืม ๆวิธีการใช้บ้าง สามารถตัวอย่างได้จาก 13 ท่า Reduce Array สยอง

ทิ้งท้าย

สุดท้ายวิธีที่ดีก็คือวิธีที่คิดออกได้ง่าย เข้าใจง่าย และอย่าลืมคำนึงถึง time complexity ด้วย โดยต้องระลึกไว้เสมอว่า function ทั้งหมดนี้เป็นการวนลูป ถ้าเรียกใช้หลายๆครั้งอาจมีผลเรื่องความล่าช้าได้ครับ

References