13 ท่า Reduce Array สยอง
ตัวอย่างไอเดียใช้ Reduce ในการทำงาน
พวกเราที่เขียน 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 - 3const pipe = (...fns) => input => fns.reduce((prev, cur) => cur(prev), input)pipe(add1, multiply5, minus3)(10)
// 52
ก็จบบทความกันไปแค่นี้นะครับ ใครงง ก็ช่วยไม่ได้ อ่านซ้ำๆ ลองเขียนซ้ำๆ กันดูนะครับ บาย