0Pricing
Scala for Backend Engineering & Functional Programming · บทเรียน

การพับและการลดค่า

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 — รูปแบบที่ปลอดภัย โดยคืนค่าเป็น Option
  • foldLeft — ค่าเริ่มต้นและตัวสะสม ปลอดภัยต่อสแตก และให้ชนิดผลลัพธ์ที่ยืดหยุ่น
  • 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 ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. List, Vector, Set, Map
  2. การแปลงข้อมูล
  3. การพับและการลดค่า
  4. การจัดกลุ่มและการเรียงลำดับ
← กลับไปที่ Scala for Backend Engineering & Functional Programming