如何在某些条件下从列表中删除重复项,underscore.js?

How to drop duplicates from list with some condition, underscore.js?

我尝试通过电子邮件删除重复的对象,但有一些条件。

假设我有以下对象列表:

var contacts = [{
    "email": {
        "value": "email1@gmail.com"
      }
  },
  {
    "displayName": "name 1",
    "email": {
        "value": "email1@gmail.com"
      }
  }
]; 

我有 600 件物品,我想删除所有重复项 但是 如果我有 2 件物品使用相同的电子邮件,但在一件物品中我有 displayName 和在其他没有这样的字段中 -> 将项目保留为 displayName.

 contacts = _.unique(contacts, function(contact){
    return contact.email.value;
 });

这是我玩的Fiddle

请帮忙,

既然你标记了下划线,我给你的解决方案只有函数。

console.log(_.chain(contacts)
    .groupBy(function(contact) {
        return contact.email.value;
    })
    .values()
    .map(function(contacts) {
        var parts = _.partition(contacts, _.partial(_.has, _, 'displayName'));
        return parts[parts[0].length ? 0 : 1][0];
    })
    .value()
);
# [ { displayName: 'name 1', email: { value: 'email1@gmail.com' } } ]

它首先根据email.value对所有联系人进行分组,然后仅选择键值对分组的values。然后根据每个组是否具有 displayName 属性 的事实对每个组进行分区。如果当前组有它,那么 return 来自第一个分区的第一项,否则来自第二个分区。

避免在分区中进行整个扫描的另一种方法:

var contacts = [{
    "email": {
        "value": "email1@gmail.com"
      }
  },
  {
    "displayName": "name 1",
    "email": {
        "value": "email1@gmail.com"
      }
  },
  {
    "displayName": "name 2",
    "email": {
        "value": "email2@gmail.com"
      }
  }
];

var filteredContacts =
    _.chain(contacts)
    .groupBy( // group contacts by email
        function(contact) { return contact.email.value; }
    )
    .values()
    .map(
        function(email_contacts) {
            return _.find( // find the first contact with the *displayName* property...
                email_contacts,
                function(contact) { return contact.displayName; }
            ) || email_contacts[0] // ... or return the first contact
        }
    )
    .value();

// returns
// [
//   {
//     "displayName": "name 1",
//     "email": {
//       "value": "email1@gmail.com"
//     }
//   },
//   {
//     "displayName": "name 2",
//     "email": {
//       "value": "email2@gmail.com"
//     }
//   }