ฉันจะใช้วิธีการรวมใน lodash เพื่อตรวจสอบว่าวัตถุอยู่ในคอลเลกชันได้อย่างไร


146

lodash ให้ฉันตรวจสอบการเป็นสมาชิกของชนิดข้อมูลพื้นฐานด้วยincludes:

_.includes([1, 2, 3], 2)
> true

แต่สิ่งต่อไปนี้ใช้ไม่ได้:

_.includes([{"a": 1}, {"b": 2}], {"b": 2})
> false

สิ่งนี้ทำให้ฉันสับสนเพราะวิธีการต่อไปนี้ที่ค้นหาคอลเลกชันดูเหมือนจะทำได้ดี:

_.where([{"a": 1}, {"b": 2}], {"b": 2})
> {"b": 2}
_.find([{"a": 1}, {"b": 2}], {"b": 2})
> {"b": 2}

ผมทำอะไรผิดหรือเปล่า? ฉันจะตรวจสอบการเป็นสมาชิกของวัตถุในคอลเล็กชันด้วยได้includesอย่างไร

แก้ไข: คำถามเดิมสำหรับ Lodash รุ่น 2.4.1, อัปเดตสำหรับ lodash 4.0.0


7
_.containsถูกลบใน lodash v4 - ใช้_.includesแทน
Billy Moon

@BillyMoon วูบ! ใช่คุณพูดถูก, lodash v4.0.0 (เผยแพร่เมื่อ 2016-01-12) จะลบcontainsชื่อแทนออก ฉันจะอัปเดตสิ่งนี้
Conrad.Dean

คำตอบ:


222

วิธีการincludes(เดิมเรียกว่าcontainsและinclude) เปรียบเทียบวัตถุโดยอ้างอิง (หรือแม่นยำมากขึ้นด้วย===) เนื่องจากวัตถุสองตัว{"b": 2}ในตัวอย่างของคุณแสดงถึงอินสแตนซ์ต่างกันจึงไม่เท่ากัน หมายเหตุ:

({"b": 2} === {"b": 2})
> false

อย่างไรก็ตามสิ่งนี้จะได้ผลเนื่องจากมีเพียงตัวอย่างเดียวเท่านั้น{"b": 2}:

var a = {"a": 1}, b = {"b": 2};
_.includes([a, b], b);
> true

ในทางตรงกันข้ามwhere(คัดค้านใน v4) และfindวิธีการเปรียบเทียบวัตถุตามคุณสมบัติของพวกเขาดังนั้นพวกเขาไม่ต้องการความเท่าเทียมกันอ้างอิง เป็นทางเลือกที่includesคุณอาจต้องการที่จะลองsome(ยังเป็นนามแฝงany):

_.some([{"a": 1}, {"b": 2}], {"b": 2})
> true

12

เสริมคำตอบจากp.s.w.gที่นี่สามวิธีการอื่น ๆ ของการบรรลุนี้โดยใช้lodash 4.17.5, โดยไม่ต้องใช้ _.includes() :

สมมติว่าคุณต้องการเพิ่มวัตถุentryไปยังอาร์เรย์ของวัตถุnumbersหาก entryไม่มีอยู่แล้ว

let numbers = [
    { to: 1, from: 2 },
    { to: 3, from: 4 },
    { to: 5, from: 6 },
    { to: 7, from: 8 },
    { to: 1, from: 2 } // intentionally added duplicate
];

let entry = { to: 1, from: 2 };

/* 
 * 1. This will return the *index of the first* element that matches:
 */
_.findIndex(numbers, (o) => { return _.isMatch(o, entry) });
// output: 0


/* 
 * 2. This will return the entry that matches. Even if the entry exists
 *    multiple time, it is only returned once.
 */
_.find(numbers, (o) => { return _.isMatch(o, entry) });
// output: {to: 1, from: 2}


/* 
 * 3. This will return an array of objects containing all the matches.
 *    If an entry exists multiple times, if is returned multiple times.
 */
_.filter(numbers, _.matches(entry));
// output: [{to: 1, from: 2}, {to: 1, from: 2}]

หากคุณต้องการส่งคืน a Booleanในกรณีแรกคุณสามารถตรวจสอบดัชนีที่จะส่งคืนได้:

_.findIndex(numbers, (o) => { return _.isMatch(o, entry) }) > -1;
// output: true
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.