REDUCE เป็นฟังก์ชัน Helper ที่ทำงานร่วมกับ LAMBDA เพื่อวนลูปประมวลผลข้อมูลใน Array โดยรับค่าเริ่มต้น (initial_value) และส่งค่าเข้า LAMBDA ทีละ element เพื่อคำนวณค่าสะสม (accumulator) ที่สืบเนื่องจากรอบก่อนหน้า แล้ว return ผลลัพธ์สุดท้ายเพียงค่าเดียว ต่างจาก SCAN ที่ return Array ของทุกขั้นตอน REDUCE เหมาะสำหรับการสร้าง custom aggregation ที่ซับซ้อนกว่าฟังก์ชันมาตรฐาน
=REDUCE([initial_value], array, lambda)
=REDUCE([initial_value], array, lambda)
| Argument | Type | Required | Default | Description |
|---|---|---|---|---|
| initial_value | Any | Optional | ค่าแรกของ Array | ค่าเริ่มต้นสำหรับ accumulator ถ้าไม่ระบุ Excel จะใช้ element แรกของ Array เป็นค่าเริ่มต้นและเริ่มวนลูปที่ element ที่ 2 แนะนำให้ระบุชัดเจนเสมอเพื่อหลีกเลี่ยง data type ไม่ตรงกัน (เช่น 0 สำหรับ sum, 1 สำหรับ product, “” สำหรับ text) |
| array | Range/Array | Yes | ช่วงข้อมูลหรือ Array ที่ต้องการประมวลผล สามารถเป็น range reference (เช่น A1:A10), named range, table column (เช่น Sales[Amount]), หรือ array constant (เช่น {1,2,3,4,5}) | |
| lambda | Function | Yes | ฟังก์ชัน LAMBDA ที่ต้องรับพารามิเตอร์ 2 ตัว: accumulator (ค่าสะสมจากรอบก่อนหน้า) และ value (element ปัจจุบันจาก Array) แล้ว return ค่าที่จะเป็น accumulator ของรอบถัดไป สูตร LAMBDA มีรูปแบบ LAMBDA(a, v, expression) โดย a = accumulator, v = current value |
สร้างการคำนวณแบบกำหนดเองเช่น sum เฉพาะเลขคู่, count เฉพาะค่าที่มากกว่าค่าเฉลี่ย, หรือ product ของเฉพาะค่าบวก ซึ่ง SUMIF/COUNTIF ทำไม่ได้เพราะต้องใช้ฟังก์ชันใน criteria
รวมข้อความโดยกรองเฉพาะข้อมูลที่ต้องการ เช่น concatenate เฉพาะชื่อที่ยาวกว่า 3 ตัวอักษร หรือรวมเฉพาะค่าที่ไม่ซ้ำ ซึ่ง TEXTJOIN ทำเงื่อนไขซับซ้อนไม่ได้
ใช้ REDUCE วนลูป SUBSTITUTE เพื่อแทนที่หลายคำพร้อมกัน เช่น แก้คำผิดหลายคำในข้อความเดียว หรือทำ data cleansing โดยลบอักขระพิเศษหลายตัวออกจากข้อความ
คำนวณแบบต่อเนื่องที่แต่ละขั้นตอนขึ้นกับผลลัพธ์ก่อนหน้า เช่น คำนวณดอกเบี้ยทบต้น, running balance ของบัญชี, หรือการคำนวณที่ผลของรอบก่อนเป็น input ของรอบถัดไป
สร้าง Array ใหม่จากข้อมูลเดิมโดยมีเงื่อนไขซับซ้อน เช่น รวม Array หลายชุดแบบมีเงื่อนไข หรือแปลงข้อมูลที่ไม่สามารถใช้ MAP ได้เพราะต้องอ้างอิงผลลัพธ์ก่อนหน้า
REDUCE(0, {1,2,3,4,5}, LAMBDA(a, v, a+v))=REDUCE(0, {1,2,3,4,5}, LAMBDA(a, v, a+v))
15
REDUCE(0, {5,3,9,1,7}, LAMBDA(a, v, MAX(a, v)))=REDUCE(0, {5,3,9,1,7}, LAMBDA(a, v, MAX(a, v)))
9
REDUCE(0, {1,2,3,4,5,6,7,8,9,10}, LAMBDA(a, v, IF(ISEVEN(v), a+v, a)))=REDUCE(0, {1,2,3,4,5,6,7,8,9,10}, LAMBDA(a, v, IF(ISEVEN(v), a+v, a)))
30
REDUCE("", {"John","Al","Michael","Bob","Tom"}, LAMBDA(a, v, IF(LEN(v)>3, IF(a="", v, a&", "&v), a)))=REDUCE("", {"John","Al","Michael","Bob","Tom"}, LAMBDA(a, v, IF(LEN(v)>3, IF(a="", v, a&", "&v), a)))
"John, Michael"
REDUCE("Hello World, Good Morning", {"Hello","World","Good"}, LAMBDA(txt, word, SUBSTITUTE(txt, word, "Hi")))=REDUCE("Hello World, Good Morning", {"Hello","World","Good"}, LAMBDA(txt, word, SUBSTITUTE(txt, word, "Hi")))
"Hi Hi, Hi Morning"
REDUCE(0, {5,12,3,18,7,21,9}, LAMBDA(a, v, IF(v>10, a+1, a)))=REDUCE(0, {5,12,3,18,7,21,9}, LAMBDA(a, v, IF(v>10, a+1, a)))
3
LET( text, "XL training and PPT training", find_list, {"XL","PPT"}, replace_list, {"Excel","PowerPoint"}, REDUCE(text, SEQUENCE(ROWS(find_list)), LAMBDA(txt, i,…=LET(
text, "XL training and PPT training",
find_list, {"XL","PPT"},
replace_list, {"Excel","PowerPoint"},
REDUCE(text, SEQUENCE(ROWS(find_list)),
LAMBDA(txt, i,
SUBSTITUTE(txt,
INDEX(find_list, i),
INDEX(replace_list, i)
)
)
)
)
"Excel training and PowerPoint training"
LET( principal, 10000, monthly_deposit, 1000, annual_rate, 0.06, months, 12, monthly_rate, annual_rate/12, REDUCE(principal, SEQUENCE(months), LAMBDA(balance, m…=LET(
principal, 10000,
monthly_deposit, 1000,
annual_rate, 0.06,
months, 12,
monthly_rate, annual_rate/12,
REDUCE(principal, SEQUENCE(months),
LAMBDA(balance, month,
(balance + monthly_deposit) * (1 + monthly_rate)
)
)
)
23563.50
ความแตกต่างหลักคือประเภทของผลลัพธ์:
.
**REDUCE:**
• Return ผลลัพธ์สุดท้ายค่าเดียว (single value)
• เหมาะสำหรับ final result เช่น ผลรวมสุดท้าย, ข้อความที่รวมเสร็จ
• ตัวอย่าง: =REDUCE(0, {1,2,3,4,5}, LAMBDA(a,v,a+v)) → 15
.
**SCAN:**
• Return Array ของผลลัพธ์ทุกขั้นตอน (array of intermediate results)
• เหมาะสำหรับ running totals, progressive results
• ตัวอย่าง: =SCAN(0, {1,2,3,4,5}, LAMBDA(a,v,a+v)) → {1;3;6;10;15}
.
**เมื่อไหร่ใช้อะไร:**
• ใช้ REDUCE เมื่อต้องการแค่ผลลัพธ์สุดท้าย (aggregate value)
• ใช้ SCAN เมื่อต้องการเห็นผลสะสมทุกขั้นตอน (running results, cumulative totals)
.
ทั้งสองฟังก์ชันใช้ LAMBDA เหมือนกันและมี syntax คล้ายกัน แตกต่างแค่ output ครับ
ถ้าไม่ระบุ initial_value ไว้ Excel จะทำ 2 สิ่ง:
.
1. **ใช้ element แรกของ Array เป็น initial_value**
2. **เริ่มวนลูปที่ element ที่ 2** (ข้าม element แรก)
.
**ตัวอย่าง:**
“`
=REDUCE(, {10,20,30}, LAMBDA(a,v,a+v))
• รอบ 1: a=10 (ค่าแรกใน Array), v=20 → 10+20=30
• รอบ 2: a=30, v=30 → 30+30=60
ผลลัพธ์: 60
“`
.
**ข้อควรระวัง:**
• Data type อาจไม่ตรงกับที่ต้องการ (เช่น คาดหวัง 0 แต่ได้ text)
• การคูณจะผิดถ้า element แรกไม่ใช่ 1
• อ่านสูตรยากขึ้นเพราะไม่ชัดเจนว่าค่าเริ่มต้นคืออะไร
.
**Best Practice:** ระบุ initial_value ชัดเจนเสมอ:
• 0 สำหรับ sum
• 1 สำหรับ product
• “” (empty text) สำหรับ concatenation
• 0 หรือ -999999 สำหรับ MAX/MIN
.
ส่วนตัวผมแนะนำให้ใส่เสมอนะครับ จะได้อ่านสูตรง่ายกว่า
**Accumulator** (มักตั้งชื่อ `a` หรือ `acc`) คือตัวแปรที่เก็บค่าสะสมระหว่างการวนลูป
.
**วงจรการทำงาน:**
1. **รอบแรก:** a = initial_value
2. **รอบถัดไป:** a = ผลลัพธ์ที่ LAMBDA return จากรอบก่อน
3. **รอบสุดท้าย:** REDUCE return ค่า a ของรอบสุดท้าย
.
**ตัวอย่างเห็นภาพ:**
“`
=REDUCE(0, {5,10,15}, LAMBDA(a,v,a+v))
รอบ 1:
Input: a=0 (initial), v=5 (element แรก)
Process: a+v = 0+5 = 5
Return: 5 → จะเป็น a ของรอบถัดไป
รอบ 2:
Input: a=5 (จากรอบก่อน), v=10 (element ที่ 2)
Process: a+v = 5+10 = 15
Return: 15 → จะเป็น a ของรอบถัดไป
รอบ 3:
Input: a=15 (จากรอบก่อน), v=15 (element สุดท้าย)
Process: a+v = 15+15 = 30
Return: 30 → จบการวนลูป
ผลลัพธ์สุดท้าย: 30
“`
.
**Key Point:** LAMBDA ต้อง return ค่าที่จะกลายเป็น accumulator ของรอบถัดไป ดังนั้นต้องคิดว่าอยากให้ค่าสะสมเป็นอะไรหลังจากประมวลผล element ปัจจุบันแล้ว
.
เข้าใจตรงนี้แล้ว จะเขียน REDUCE ได้คล่องมากขึ้นครับ
**ตอบสั้นๆ: ไม่เหมาะครับ**
.
REDUCE return ค่าสุดท้ายค่าเดียว ไม่ใช่ Array ของทุกขั้นตอน
.
**ถ้าใช้ REDUCE:**
“`
=REDUCE(0, {10,20,30,40}, LAMBDA(a,v,a+v))
ผลลัพธ์: 100 (ผลรวมสุดท้ายค่าเดียว)
“`
.
**ถ้าต้องการ Running Total ต้องใช้ SCAN:**
“`
=SCAN(0, {10,20,30,40}, LAMBDA(a,v,a+v))
ผลลัพธ์: {10;30;60;100} (Array แสดงผลสะสมทุกขั้น)
“`
.
**เมื่อไหร่ใช้อะไร:**
• **REDUCE:** ต้องการแค่ผลสุดท้าย → ผลรวม, ข้อความที่รวมเสร็จ, ค่าสูงสุด
• **SCAN:** ต้องการเห็นทุกขั้นตอน → Running Total, Cumulative Sum, กราฟแสดงความคืบหน้า
.
ถ้าใช้ REDUCE ทำ Running Total จะได้แค่ตัวเลขสุดท้ายมาตัวเดียว ซึ่งไม่ใช่สิ่งที่ต้องการนะครับ
REDUCE เป็น LAMBDA Helper Function ที่รองรับเฉพาะ:
.
**✅ รองรับ:**
• Microsoft 365 (subscription)
• Excel 2024
• Excel for the web
• Excel for Mac (Microsoft 365)
.
**❌ ไม่รองรับ:**
• Excel 2021 หรือเก่ากว่า
• Excel 2019
• Excel 2016
• Excel 2013
• Standalone versions ที่ไม่ใช่ subscription
.
**วิธีตรวจสอบ:**
พิมพ์ =REDUCE( ใน cell ถ้า Excel แสดง tooltip คำแนะนำพารามิเตอร์แสดงว่ารองรับ ถ้าขึ้น #NAME? error แสดงว่า Excel version นั้นไม่รองรับ
.
**Alternative สำหรับ Excel เก่า:**
ถ้าไม่มี REDUCE ต้องใช้วิธีอื่นแทน:
• สร้าง Helper Column คำนวณทีละขั้น
• ใช้ VBA User-Defined Function
• ใช้ Power Query (สำหรับ data transformation)
• Nested formulas (อ่านยาก แต่ทำได้บางกรณี)
.
ส่วนตัวผมแนะนำให้ update เป็น Microsoft 365 นะครับ จะได้ใช้ LAMBDA ครอบครัวได้หมดเลย
**ใช่ REDUCE ช้ากว่าฟังก์ชันมาตรฐาน** แต่ความต่างขึ้นกับขนาดข้อมูลครับ
.
**Performance Comparison:**
• ข้อมูลน้อย (10,000 rows): REDUCE ช้ากว่าชัดเจน
.
**ตัวอย่าง:**
• =SUM(A1:A10000) → เร็วมาก (optimized C++ code)
• =REDUCE(0, A1:A10000, LAMBDA(a,v,a+v)) → ช้ากว่า (วนลูปทีละ cell)
.
**Best Practice:**
1. **ใช้ฟังก์ชันมาตรฐานก่อนเสมอ** ถ้าทำได้:
• SUM, AVERAGE, MAX, MIN → ใช้เลย อย่าใช้ REDUCE
• SUMIF, COUNTIF → ถ้าเงื่อนไขง่าย ใช้อันนี้
.
2. **ใช้ REDUCE เมื่อ:**
• ฟังก์ชันมาตรฐานทำไม่ได้
• เงื่อนไขซับซ้อนเกินไป (เช่น sum เฉพาะเลขคู่)
• ต้องการ sequential calculation
.
3. **Optimization Tips:**
• ถ้าข้อมูลเยอะมาก ลอง Filter ก่อนใส่ REDUCE
• ใช้ LET เก็บค่าที่คำนวณซ้ำ
• พิจารณาใช้ Helper Column แทน ถ้า performance สำคัญมาก
.
**สรุป:** REDUCE ให้ flexibility แลกกับ speed ใช้เมื่อจำเป็นจริงๆ นะครับ
ทั้งคู่เป็น LAMBDA Helper Functions แต่ใช้งานต่างกันครับ:
.
**REDUCE:**
• **วัตถุประสงค์:** รวม Array เป็นค่าเดียว (aggregate)
• **Input:** Array + LAMBDA ที่รับ 2 parameters (accumulator, value)
• **Output:** Single value (ค่าเดียว)
• **Use Case:** Sum, Max, Concatenate, Count, คำนวณค่าสุดท้าย
• **ตัวอย่าง:** =REDUCE(0, {1,2,3}, LAMBDA(a,v,a+v)) → 6
.
**MAP:**
• **วัตถุประสงค์:** แปลงทุก element ใน Array (transform)
• **Input:** Array + LAMBDA ที่รับ 1 parameter (value)
• **Output:** Array ที่มีขนาดเท่าเดิม แต่ค่าถูกแปลง
• **Use Case:** คูณทุกตัวด้วย 2, เปลี่ยนเป็น UPPER, คำนวณ formula สำหรับทุก element
• **ตัวอย่าง:** =MAP({1,2,3}, LAMBDA(v,v*2)) → {2,4,6}
.
**เปรียบเทียบแบบเห็นภาพ:**
“`
Array เริ่มต้น: {10, 20, 30}
MAP (transform):
{10, 20, 30} → apply LAMBDA(v, v*2)
→ {20, 40, 60} (ขนาด Array เท่าเดิม, ค่าถูกแปลง)
REDUCE (aggregate):
{10, 20, 30} → apply LAMBDA(a,v, a+v) with initial=0
→ 60 (ได้ค่าเดียว)
“`
.
**Key Difference:**
• MAP: One-to-one mapping (1 input → 1 output per element)
• REDUCE: Many-to-one reduction (many inputs → 1 output)
.
**เมื่อไหร่ใช้อะไร:**
• **MAP:** ต้องการแปลงทุกค่า → คูณ, หาร, เปลี่ยน format
• **REDUCE:** ต้องการรวมเป็นค่าเดียว → sum, max, concatenate
.
เข้าใจความต่างตรงนี้ แล้วจะเลือกใช้ได้ถูกต้องครับ
**ได้ครับ แต่จะวนลูปแบบ row-by-row หรือ column-by-column**
.
REDUCE จะประมวลผล 2D Array ทีละแถว (ถ้า Array เป็น vertical) หรือทีละคอลัมน์ (ถ้า Array เป็น horizontal)
.
**ตัวอย่างที่ 1: Sum ทุกค่าใน 2D Array**
“`
=REDUCE(0, A1:C3,
LAMBDA(total, row,
total + SUM(row)
)
)
“`
.
ถ้า A1:C3 มีข้อมูล:
“`
1 2 3
4 5 6
7 8 9
“`
.
REDUCE จะวนลูป:
• รอบ 1: row={1,2,3} → total=0+SUM({1,2,3})=6
• รอบ 2: row={4,5,6} → total=6+SUM({4,5,6})=21
• รอบ 3: row={7,8,9} → total=21+SUM({7,8,9})=45
.
ผลลัพธ์: 45
.
**Tips สำหรับ 2D Array:**
• ใช้ BYCOL/BYROW ร่วมกับ REDUCE สำหรับ control ที่ดีกว่า
• ถ้าต้องการวนลูปทีละ cell ใช้ TOCOL() แปลงเป็น 1D ก่อน
• Nested REDUCE สามารถวนลูป 2 dimensions ได้
.
**Alternative:**
ถ้าต้องการประมวลผลทีละคอลัมน์/แถว ใช้ BYCOL/BYROW จะง่ายกว่า:
“`
=BYCOL(A1:C3, LAMBDA(col, SUM(col)))
“`
.
REDUCE เหมาะกับ 1D Array มากกว่า สำหรับ 2D ควรพิจารณา BYCOL/BYROW ก่อนนะครับ
REDUCE เป็น LAMBDA Helper Function ที่ใช้วนลูปผ่านทุก element ใน Array และคำนวณค่าสะสม (accumulator) ด้วย LAMBDA ที่กำหนดเอง จนได้ผลลัพธ์สุดท้ายเพียงค่าเดียว
.
ต่างจาก SCAN ที่ return Array ของทุกขั้นตอน REDUCE return เฉพาะค่าสุดท้าย เหมาะสำหรับการสร้าง custom aggregation เช่น conditional sum ที่ซับซ้อนกว่า SUMIF, text concatenation แบบมีเงื่อนไข, batch find-replace หลายคำพร้อมกัน หรือการคำนวณแบบ sequential ที่ขั้นตอนถัดไปขึ้นกับผลลัพธ์ก่อนหน้า
.
เอาจริงๆ REDUCE เป็นฟังก์ชันที่ทรงพลังมาก แต่ต้องเข้าใจ concept ของ accumulator ให้ดีก่อนนะครับ พอเข้าใจแล้วจะเปิดโลกใหม่ให้กับการทำงานกับ Array เลย 😎