var index = list.findIndex(item => item.name === "three")
list = list.setIn([index, "count"], 4)
คำอธิบาย
การอัปเดตคอลเล็กชัน Immutable.js จะส่งคืนเวอร์ชันใหม่ของคอลเล็กชันเหล่านั้นเสมอโดยปล่อยให้ต้นฉบับไม่เปลี่ยนแปลง ด้วยเหตุนี้เราจึงไม่สามารถใช้list[2].count = 4ไวยากรณ์การกลายพันธุ์ของ JavaScript ได้ แต่เราจำเป็นต้องเรียกใช้เมธอดเหมือนกับที่เราทำกับคลาสคอลเลกชัน Java
เริ่มจากตัวอย่างที่ง่ายกว่านี้: จำนวนในรายการ
var arr = [];
arr.push(2);
arr.push(1);
arr.push(2);
arr.push(1);
var counts = Immutable.List.of(arr);
ตอนนี้ถ้าเราต้องการที่จะปรับปรุงรายการที่ 3 ธรรมดา JS counts[2] = 4อาร์เรย์อาจมีลักษณะเช่น: เนื่องจากเราไม่สามารถใช้การกลายพันธุ์และจำเป็นที่จะต้องเรียกวิธีการแทนเราสามารถใช้: counts.set(2, 4)- ที่หมายถึงการตั้งค่าที่ดัชนี42
การอัปเดตเชิงลึก
ตัวอย่างที่คุณให้มามีข้อมูลซ้อนกัน เราไม่สามารถใช้set()กับคอลเลกชันเริ่มต้นได้
คอลเล็กชัน Immutable.js มีกลุ่มวิธีการที่มีชื่อลงท้ายด้วย "In" ซึ่งช่วยให้คุณทำการเปลี่ยนแปลงในระดับที่ลึกกว่าในชุดที่ซ้อนกันได้ วิธีการอัปเดตทั่วไปส่วนใหญ่มีวิธี "ใน" ที่เกี่ยวข้อง ตัวอย่างเช่นสำหรับการมีset setInแทนที่จะยอมรับดัชนีหรือคีย์เป็นอาร์กิวเมนต์แรกเมธอด "In" เหล่านี้จะยอมรับ "เส้นทางคีย์" คีย์พา ธ คืออาร์เรย์ของดัชนีหรือคีย์ที่แสดงให้เห็นถึงวิธีการไปยังค่าที่คุณต้องการอัปเดต
ในตัวอย่างของคุณคุณต้องการอัปเดตรายการในรายการที่ดัชนี 2 จากนั้นจึงกำหนดค่าที่คีย์ "count" ภายในรายการนั้น ดังนั้นเส้นทางสำคัญก็[2, "count"]คือ พารามิเตอร์ที่สองของsetInวิธีการทำงานเหมือนกับsetค่าใหม่ที่เราต้องการใส่ไว้ที่นั่นดังนั้น:
list = list.setIn([2, "count"], 4)
ค้นหาเส้นทางสำคัญที่ถูกต้อง
ไปอีกขั้นหนึ่งคุณเคยบอกว่าคุณต้องการอัปเดตรายการที่ชื่อ "สาม"ซึ่งแตกต่างจากรายการที่ 3 ตัวอย่างเช่นรายการของคุณอาจไม่ได้รับการจัดเรียงหรืออาจมีการนำรายการชื่อ "two" ออกก่อนหน้านี้ นั่นหมายความว่าอันดับแรกเราต้องแน่ใจว่าเรารู้เส้นทางสำคัญที่ถูกต้องจริงๆ! สำหรับสิ่งนี้เราสามารถใช้findIndex()วิธีการ (ซึ่งโดยวิธีการทำงานเกือบจะเหมือนกับArray # findIndex )
เมื่อเราพบดัชนีในรายการซึ่งมีรายการที่เราต้องการอัปเดตเราสามารถระบุเส้นทางสำคัญไปยังค่าที่เราต้องการอัปเดตได้:
var index = list.findIndex(item => item.name === "three")
list = list.setIn([index, "count"], 4)
หมายเหตุ: SetเทียบกับUpdate
คำถามเดิมกล่าวถึงวิธีการอัพเดตมากกว่าวิธีการตั้งค่า ฉันจะอธิบายอาร์กิวเมนต์ที่สองในฟังก์ชันนั้น (เรียกว่าupdater) เนื่องจากมันแตกต่างจากset(). ในขณะที่อาร์กิวเมนต์ที่สองset()เป็นค่าใหม่ที่เราต้องการอาร์กิวเมนต์ที่สองupdate()เป็นฟังก์ชันที่ยอมรับค่าก่อนหน้าและส่งคืนค่าใหม่ที่เราต้องการ จากนั้นupdateIn()เป็นรูปแบบ "ใน" update()ที่ยอมรับเส้นทางสำคัญ
สมมติว่าเราต้องการรูปแบบของตัวอย่างของคุณที่ไม่เพียงแค่ตั้งค่าการนับเป็น4แต่เพิ่มจำนวนที่มีอยู่แทนเราสามารถจัดเตรียมฟังก์ชันที่เพิ่มค่าหนึ่งเข้าไปในค่าที่มีอยู่:
var index = list.findIndex(item => item.name === "three")
list = list.updateIn([index, "count"], value => value + 1)