ค้นหาเว็บไซต์

json - การลบวัตถุซ้ำด้วย Underscore สำหรับ Javascript


ฉันมีอาเรย์ประเภทนี้:

var foo = [ { "a" : "1" }, { "b" : "2" }, { "a" : "1" } ];

ฉันต้องการกรองให้มี:

var bar = [ { "a" : "1" }, { "b" : "2" }];

ฉันลองใช้ _.uniq แต่ผมคิดว่าเพราะ { "a" : "1" } ไม่เท่ากับตัวมันเอง มันเลยไม่ทำงาน มีวิธีใดบ้างที่จะให้ underscore uniq มีฟังก์ชัน equals ที่ถูกเขียนทับ?

คำตอบ #1

.uniq/.unique รับฟังก์ชัน callback

var list = [{a:1,b:5},{a:1,c:5},{a:2},{a:3},{a:4},{a:3},{a:2}];

var uniqueList = _.uniq(list, function(item, key, a) { 
    return item.a;
});

// uniqueList = [Object {a=1, b=5}, Object {a=2}, Object {a=3}, Object {a=4}]

บันทึก:

  1. ค่าที่ส่งกลับจากการเรียกกลับใช้สำหรับการเปรียบเทียบ
  2. วัตถุเปรียบเทียบแรกที่มีค่าผลลัพธ์เฉพาะใช้เป็นค่าที่ไม่ซ้ำกัน
  3. underscorejs.org แสดงการใช้งานโดยไม่ใช้ callback
  4. lodash.com แสดงการใช้งาน

ตัวอย่างอีกหนึ่ง : ใช้ callback เพื่อดึงยี่ห้อรถและสีจากรายการ

คำตอบ #2

ถ้าคุณกำลังมองหาวิธีลบข้อมูลซ้ำตามรหัส คุณสามารถทำอะไรทำนองนี้ได้:

var res = [
  {id: 1, content: 'heeey'},
  {id: 2, content: 'woah'}, 
  {id: 1, content:'foo'},
  {id: 1, content: 'heeey'},
];
var uniques = _.map(_.groupBy(res,function(doc){
  return doc.id;
}),function(grouped){
  return grouped[0];
});

//uniques
//[{id: 1, content: 'heeey'},{id: 2, content: 'woah'}]

คำตอบ #3

การนำคำตอบของ Shiplu มาปฏิบัติ

var foo = [ { "a" : "1" }, { "b" : "2" }, { "a" : "1" } ];

var x = _.uniq( _.collect( foo, function( x ){
    return JSON.stringify( x );
}));

console.log( x ); // returns [ { "a" : "1" }, { "b" : "2" } ]

คำตอบ #4

เมื่อฉันมีคุณลักษณะ id นี่คือวิธีที่ฉันชอบใช้ใน underscore:

var x = [{i:2}, {i:2, x:42}, {i:4}, {i:3}];
_.chain(x).indexBy("i").values().value();
// > [{i:2, x:42}, {i:4}, {i:3}]

คำตอบ #5

การใช้ไลบรารี underscore unique ดังต่อไปนี้ใช้งานได้สำหรับฉัน ฉันกำลังสร้างรายการที่ไม่ซ้ำกันโดยอิงจาก _id แล้วคืนค่าค่า String ของ _id:

var uniqueEntities = _.uniq(entities, function (item, key, a) {
                                    return item._id.toString();
                                });

คำตอบ #6

นี่คือตัวแก้ปัญหาง่าย ๆ ซึ่งใช้การเปรียบเทียบวัตถุอย่างลึกเพื่อตรวจหาสิ่งซ้ำ (โดยไม่ต้องแปลงเป็น JSON ซึ่งไม่ประสิทธิภาพและเป็นวิธีแก้ปัญหาแบบไม่เป็นทางการ)

var newArr = _.filter(oldArr, function (element, index) {
    // tests if the element has a duplicate in the rest of the array
    for(index += 1; index < oldArr.length; index += 1) {
        if (_.isEqual(element, oldArr[index])) {
            return false;
        }
    }
    return true;
});

มันกรองเอาองค์ประกอบทั้งหมดออกถ้าพวกมันมีค่าซ้ำในภายหลังในอาร์เรย์ - โดยเก็บเฉพาะองค์ประกอบซ้ำตัวสุดท้าย

การทดสอบหาสิ่งที่ซ้ำกันใช้ _.isEqual ซึ่งทำการเปรียบเทียบเชิงลึกที่ปรับให้เหมาะสมระหว่างวัตถุทั้งสอง ดูเอกสารของ underscore isEqual สำหรับข้อมูลเพิ่มเติม

แก้ไข: อัปเดตเพื่อใช้ _.filter ซึ่งเป็นวิธีที่สะอาดกว่า

คำตอบ #7

เอกสารของ lodash 4.6.1 มีตัวอย่างนี้สำหรับความเท่าเทียมของคีย์วัตถุ:

_.uniqWith(objects, _.isEqual);

https://lodash.com/docs#uniqWith

บทความที่เกี่ยวข้อง