13 ท่า Reduce Array สยอง

ตัวอย่างไอเดียใช้ Reduce ในการทำงาน

Nantaphop Phuengphae
True e-Logistics
Published in
3 min readMay 26, 2019

--

พวกเราที่เขียน Javascript กันมา คงเคยใช้พวก .map() หรือ .filter() กันมาบ้างแล้ว แต่ Function ที่ทรงพลังที่สุดตัวนึงของ Array ที่ชื่อว่า Reduce นั้น กลับไม่ค่อยเห็นคนใช้งานเท่าไรนัก

บางคนอาจจะกลัว บางคนอาจจะเกลียด บางคนอาจจะนึกในใจว่า “มันคือไรวะ” มีด้วยเหรอ เพราะฉะนั้น ก่อนอื่นเรามารู้จักมันกันก่อนแล้วกันนะครับ

คำอธิบาย Function Reduce ดังต่อไปนี้ ก๊อปปี้มาจาก VSCode นะครับ

(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: readonly T[]) => T): T

A function that accepts up to four arguments. The reduce method calls the callbackfn function one time for each element in the array.

Calls the specified callback function for all the elements in an array. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function.

คำศัพท์สำคัญของเรื่องราวข้างบน คือคำว่า Accumulated ที่แปลว่าถูกสะสม นะครับ ซึ่งทำให้เราเรียก Callback Function ที่เราส่งเข้าไปใน reduce ว่า Acumulator หรือแปลว่า ตัวสะสม นั่นเอง

หลักการทำงาน ก็คือ เราต้องใส่ Function ที่รับค่า ที่สะสมมา และค่าปัจจุบัน แล้ว Return ค่าใหม่ ออกมา และอีก Parameter นึงคือ ค่าตั้งต้นนะครับ อธิบายยากจัง ขอยกตัวอย่างแบบนี้นะครับ

[5, 10, 15].reduce((previous, current) => previous + current, 0)
// ค่าตั้งต้น 0
// รอบที่ 1: previous = 0 (มาจากค่าตั้งต้น), current = 5(Element ที่ 0 ของ Array) Return = 5 (มาจาก 0 + 5)// รอบที่ 2: previous = 5(มาจาก Return รอบที่ 1), current = 10(Element ที่ 1 ของ Array) Return = 15 (มาจาก 5 + 10)// รอบที่ 3: previous = 15(มาจาก Return รอบที่ 2), current = 15(Element ที่ 2ของ Array) Return = 30(มาจาก 15 + 10)

จากคำอธิบาย ก็จะได้ว่าผลลัพธ์ของเราคือ 30 นะครับ วิธีคิด คือต้องคิดเป็นรอบๆ เหมือนเวลาเราหัดเขียน Loop ถ้าใครไม่เข้าใจนั้น ก็อ่านหลายๆ รอบ Loop ไปจนเข้าใจนะครับ

เข้าเรื่องดีกว่า ต่อไปนี้ เป็นตัวอย่าง 13 ท่า การเขียน Reduce นะครับ บางตัวอย่าง มีวิธีอื่นที่เขียนง่ายกว่า แต่ขอให้ เข้าใจตรงกันนะครับ ว่าบทความนี้ ตั้งใจยกตัวอย่างการใช้ Reduce เน้อ

1. หาค่า Min ใน Array

const data = [5, 2, 8 ,33, 56, 77, 899]data.reduce((prev, cur) => cur < prev ? cur : prev)
// 2

2. หาค่า Max ใน Array

const data = [5, 2, 8 ,33, 56, 77, 899]data.reduce((prev, cur) => cur > prev ? cur : prev)
// 899

3. หาผลรวม (Sum)

const data = [5, 2, 8 ,33, 56, 77, 899]data.reduce((prev, cur) => prev + cur)
// 1080

4. เอาเฉพาะค่าที่ไม่ซ้ำกัน (Unique)

const data = [1, 3, 3, 7, 10, 10, 4]data.reduce((prev, cur) => prev.includes(cur) 
? prev : prev.concat(cur), [])
// [ 1, 3, 7, 10, 4 ]

5. กลับด้านค่าใน Array

const data = [1, 3, 3, 7, 10, 10, 4]data.reduce((prev, cur) => [cur].concat(prev), [])
// [ 4, 10, 10, 7, 3, 3, 1 ]

6. เอาตัวหนังสือมาต่อกัน

const data = ['A', 'B', 'C', 'D']data.reduce((prev, cur) => (prev + cur)
// ABCD

7. เอา Field ทั้งหมดของ Object ใน Array มารวมกัน (Assign)

const data = [
{name: 'AAA', gender: 'M'},
{name: 'BBB', phone: '0888888888'},
{name: 'DDD', email: 'mmmm@google.com'}
]
data.reduce((prev, cur) => ({...prev, ...cur}), {})
// { name: 'DDD',
gender: 'M',
phone: '0888888888',
email: 'mmmm@google.com' }

8. นับจำนวน Object ที่มี Field เป็นค่าต่างๆ เช่น นับจำนวนเพศชาย เพศหญิง ว่ามีกี่คน

const data = [
{name: 'AAA', gender: 'M'},
{name: 'BBB', gender: 'F'},
{name: 'DDD', gender: 'M'},
{name: 'E', gender: 'M'}
]
data.reduce((prev, cur) => ({
...prev,
[cur.gender]: (prev[cur.gender] || 0) + 1}),
{})
// { M: 3, F: 1 }

9. จับ Group Object ใน Array ตามค่าของ Field หนึ่ง

const data = [
{name: 'AAA', gender: 'M'},
{name: 'BBB', gender: 'F'},
{name: 'DDD', gender: 'M'},
{name: 'E', gender: 'M'}
]
data.reduce((prev, cur) => ({
...prev,
[cur.gender]: (prev[cur.gender] || []).concat(cur)
}), {})
// { M:[
{ name: 'AAA', gender: 'M' },
{ name: 'DDD', gender: 'M' },
{ name: 'E', gender: 'M' }
],
F: [
{ name: 'BBB', gender: 'F' }
]
}

10. แปลง Key-Value Pair ให้กลับมาเป็น Object

const data = [['name', 'Peter'], ['age', 30], ['gender', 'M']]data.reduce((prev, cur) => ({
...prev,
[cur[0]]: cur[1]
}), {})
// { name: 'Peter', age: 30, gender: 'M' }

11. ทำให้ Array 2 ชั้น เหลือ ชั้นเดียว

const data = [[1,2], [2,3], [4,5]]data.reduce((prev, cur) => prev.concat(cur), [])
// [ 1, 2, 2, 3, 4, 5 ]

12. ทำ Promise Chain เรียกเป็นชั้นๆ

const promise1 = val => new Promise(resolve => resolve(val + 1))const promise10 = val => new Promise(resolve => resolve(val + 10))const promise100 = val => new Promise(resolve => resolve(val + 100))const data = [promise1, promise10, promise100]const result = data.reduce((prev, cur) => prev.then(cur), Promise.resolve(1))result.then(v => console.log(v))
// 112

13. Pipe ผลลัพธ์จาก Function

const add1 = val => val + 1
const multiply5 = val => val * 5
const minus3 = val => val - 3
const pipe = (...fns) => input => fns.reduce((prev, cur) => cur(prev), input)pipe(add1, multiply5, minus3)(10)
// 52

ก็จบบทความกันไปแค่นี้นะครับ ใครงง ก็ช่วยไม่ได้ อ่านซ้ำๆ ลองเขียนซ้ำๆ กันดูนะครับ บาย

--

--