การพับและการลดค่า
foldLeft และ reduce
การพับและการลดค่า เป็นบทเรียน Scala for Backend Engineering & Functional Programming ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Scala for Backend Engineering & Functional Programming และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Scala for Backend Engineering & Functional Programming มีบทเรียนทั้งหมด 4 บทเรียน
การรวมสมาชิกให้เป็นหนึ่งเดียว
บางครั้งคุณจำเป็นต้องรวมสมาชิกทั้งหมดของคอลเลกชันให้เป็นค่าเดียว เช่น ผลรวม หรือการต่อข้อความ Scala มี fold, foldLeft, foldRight และ reduce สำหรับงานนี้
object Main {
def main(args: Array[String]): Unit = {
val nums = List(1, 2, 3, 4)
println(nums.sum)
println(nums.product)
}
}reduce: รวมโดยไม่มีค่าเริ่มต้น
reduce รวมสมาชิกทีละคู่โดยใช้ฟังก์ชันแบบทวิภาค ฟังก์ชันนี้ต้องมีสมาชิกอย่างน้อยหนึ่งรายการ มิฉะนั้นจะโยนข้อยกเว้น
object Main {
def main(args: Array[String]): Unit = {
val nums = List(1, 2, 3, 4)
val total = nums.reduce((a, b) => a + b)
println(total)
val max = nums.reduce((a, b) => if (a > b) a else b)
println(max)
}
}foldLeft: รวมโดยมีค่าเริ่มต้น
foldLeft รับค่าเริ่มต้นและฟังก์ชัน ฟังก์ชันนี้ทำงานได้อย่างปลอดภัยกับคอลเลกชันว่าง โดยคืนค่าเริ่มต้น และอนุญาตให้ชนิดของผลลัพธ์แตกต่างจากชนิดของสมาชิกได้
ไวยากรณ์: xs.foldLeft(seed)((acc, x) => ...)
object Main {
def main(args: Array[String]): Unit = {
val nums = List(1, 2, 3, 4)
val sum = nums.foldLeft(0)((acc, x) => acc + x)
println(sum)
val empty = List.empty[Int].foldLeft(0)(_ + _)
println(empty)
}
}รูปแบบตัวสะสม
ในการพับรวม อาร์กิวเมนต์ตัวแรกคือตัวสะสมซึ่งเก็บผลลัพธ์ที่คำนวณต่อเนื่อง ส่วนอาร์กิวเมนต์ตัวที่สองคือสมาชิกปัจจุบัน ในแต่ละขั้นตอน ตัวสะสมจะได้รับการอัปเดต
object Main {
def main(args: Array[String]): Unit = {
val words = List("Scala", "is", "great")
val sentence = words.foldLeft("")((acc, w) => acc + w + " ")
println(sentence.trim)
}
}ชนิดของผลลัพธ์แตกต่างกันได้
คุณสมบัติที่ทรงพลังของ foldLeft คือชนิดของตัวสะสมสามารถแตกต่างจากชนิดของสมาชิกได้ ในตัวอย่างนี้ เราพับรวมรายการตัวเลขให้เป็น String
object Main {
def main(args: Array[String]): Unit = {
val nums = List(1, 2, 3)
val joined = nums.foldLeft("nums:")((acc, n) => acc + " " + n)
println(joined)
}
}foldRight: เริ่มจากด้านขวา
foldRight ประมวลผลสมาชิกจากขวาไปซ้าย ตัวสะสมเป็นอาร์กิวเมนต์ตัวที่สอง: (x, acc) => ... ทิศทางมีความสำคัญสำหรับการดำเนินการที่สลับลำดับไม่ได้
object Main {
def main(args: Array[String]): Unit = {
val nums = List(1, 2, 3, 4)
val left = nums.foldLeft("")((acc, x) => acc + x)
val right = nums.foldRight("")((x, acc) => acc + x)
println("foldLeft: " + left)
println("foldRight: " + right)
}
}ด้านซ้ายเทียบกับด้านขวาและประสิทธิภาพ
foldLeft ใช้การเรียกตัวเองแบบท้ายและปลอดภัยต่อสแตกเมื่อใช้กับรายการขนาดใหญ่ ส่วน foldRight กับ List อาจทำให้สแตกเต็มเมื่ออินพุตมีขนาดใหญ่มาก ควรเลือกใช้ foldLeft เว้นแต่ลำดับจะบังคับให้ใช้แบบอื่น
object Main {
def main(args: Array[String]): Unit = {
val big = (1 to 100000).toList
val total = big.foldLeft(0L)((acc, x) => acc + x)
println(total)
}
}สร้างคอลเลกชันด้วย fold
การพับรวมมีความทั่วไปมากพอที่จะใช้สร้างคอลเลกชันได้ ในที่นี้เราเรียงรายการกลับด้านโดยเติมสมาชิกแต่ละรายการไว้ด้านหน้าของรายการตัวสะสม
object Main {
def main(args: Array[String]): Unit = {
val nums = List(1, 2, 3, 4)
val reversed = nums.foldLeft(List.empty[Int])((acc, x) => x :: acc)
println(reversed)
}
}reduceOption เพื่อความปลอดภัย
เนื่องจาก reduce ล้มเหลวกับคอลเลกชันว่าง reduceOption จึงคืนค่าเป็น Option แทน โดยคืน Some(result) เมื่อคอลเลกชันไม่ว่าง และคืน None เมื่อว่าง
object Main {
def main(args: Array[String]): Unit = {
println(List(3, 1, 4).reduceOption(_ + _))
println(List.empty[Int].reduceOption(_ + _))
}
}fold: รูปแบบสมมาตร
fold คล้ายกับ foldLeft แต่ตัวสะสมต้องมีชนิดเดียวกันกับสมาชิก มักใช้กับคอลเลกชันแบบขนาน
object Main {
def main(args: Array[String]): Unit = {
val nums = List(1, 2, 3, 4)
val total = nums.fold(0)(_ + _)
println(total)
}
}นับจำนวนด้วย foldLeft
การพับรวมสามารถคำนวณผลลัพธ์ที่ซับซ้อนขึ้นได้ เช่น นับจำนวนสมาชิกที่ตรงตามเงื่อนไขทั้งหมดในการประมวลผลครั้งเดียว
object Main {
def main(args: Array[String]): Unit = {
val nums = List(4, 7, 2, 9, 6, 1)
val evenCount = nums.foldLeft(0)((acc, x) => if (x % 2 == 0) acc + 1 else acc)
println(s"even numbers: $evenCount")
}
}ตรวจสอบความเข้าใจอย่างรวดเร็ว
ความแตกต่างสำคัญระหว่าง reduce กับ foldLeft คืออะไร
สรุปทบทวน
คุณได้เรียนรู้การพับรวมและการลดรูปแล้ว:
reduce— รวมทีละคู่ ไม่มีค่าเริ่มต้น และล้มเหลวเมื่อว่างreduceOption— รูปแบบที่ปลอดภัย โดยคืนค่าเป็นOptionfoldLeft— ค่าเริ่มต้นและตัวสะสม ปลอดภัยต่อสแตก และให้ชนิดผลลัพธ์ที่ยืดหยุ่นfoldRight— จากขวาไปซ้าย ต้องระวังสแตกเมื่อใช้กับรายการขนาดใหญ่- การพับรวมยังสามารถสร้างคอลเลกชันใหม่ได้
คำถามที่พบบ่อย
บทเรียน “การพับและการลดค่า” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “การพับและการลดค่า” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Scala for Backend Engineering & Functional Programming ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Scala for Backend Engineering & Functional Programming มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “การพับและการลดค่า”
foldLeft และ reduce คุณปฏิบัติ Scala for Backend Engineering & Functional Programming ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Scala for Backend Engineering & Functional Programming หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Scala for Backend Engineering & Functional Programming บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน
บทเรียน “การพับและการลดค่า” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Scala for Backend Engineering & Functional Programming นี้ได้ไหม
ได้ บทเรียน Scala for Backend Engineering & Functional Programming ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- List, Vector, Set, Map
- การแปลงข้อมูล
- การพับและการลดค่า
- การจัดกลุ่มและการเรียงลำดับ