根据多个属性删除重复项,但不是全部

时间:2016-03-10 08:24:27

标签: javascript lodash

给定对象和对象上的数组,看起来像这样:

var historyList = [
    { id: 1, name: 'Donna', data: 'phone: 903489349'},
    { id: 2, name: 'Amy', data: 'address: Street 1'},
    { id: 1, name: 'Amy', data: 'address: Street 2'}
]

var newHistoryObject = { id: 1, name: 'Amy', data: 'phone: 03492'}

我想从数组中删除与id具有相同name AND 相同newHistoryObject的任何对象。

我尝试过使用lodash isEqual,但当然这不起作用,因为还有其他属性可能不同。

我也尝试过这样:

var temp = _.filter(historyList, function(item) {
    if (newHistoryObject.name !== item.name &&
        newHistoryObject.id !== item.id) {
        return item;
    }
});

这不起作用。它只保留在这里重复的对象,并抛弃其他对象。

我想要的结果是一个数组,其中任何对象具有与"外部"相同的nameid。对象,在这种情况下是这样的:

var temp = [
    { id: 1, name: 'Donna', data: 'phone: 903489349'},
    { id: 2, name: 'Amy', data: 'address: Street 1'}
]

5 个答案:

答案 0 :(得分:2)

这是普通Javascript中的一个解决方案,它包含一个临时对象thisArray#filter()



var historyList = [{ id: 1, name: 'Donna', data: 'phone: 903489349' }, { id: 2, name: 'Amy', data: 'address: Street 1' }, { id: 1, name: 'Amy', data: 'address: Street 2' }],
    newHistoryObject = { id: 1, name: 'Amy', data: 'phone: 03492' },
    filtered = historyList.filter(function (a) {
        return a.id !== this.id || a.name !== this.name;
    }, newHistoryObject);

document.write('<pre>' + JSON.stringify(filtered, 0, 4) + '</pre>');
&#13;
&#13;
&#13;

答案 1 :(得分:0)

试试这个

var arr = [
    { id: 1, name: 'Amy', data: 'phone: 03492'},
    { id: 1, name: 'Donna', data: 'phone: 903489349'},
    { id: 2, name: 'Amy', data: 'address: Street 1'},
    { id: 1, name: 'Amy', data: 'address: Street 2'}
];
var map = {}; 
arr.forEach(function(value,index){ 
    var obj = JSON.stringify({id:value.id, name:value.name}); 
    if (!map[obj])
    { 
       map[obj] = true; 
    }
    else
    { 
       arr.splice(index,1); 
    } 
});
console.log(arr); //final output
  

我想从数组中删除任何具有相同ID的对象   与newHistoryObject同名。

historyList.forEach(function(value,index){
  if ( value.id == newHistoryObject.id && value.name == newHistoryObject.name )
  {
    historyList.splice(index,1);
  }
});
console.log(historyList);

答案 2 :(得分:0)

我尝试使用地图。

var map={};
list.forEach((o)=>{
  if(!map[o.id+o.name]){
    map[o.id+o.name]=o;
  }
});
var newlist=[];
for(var key in map){
  newlist.push(map[key]);
}

答案 3 :(得分:0)

有一些好主意,这里是尝试将最好的一起融合在一起。它使用 reduceRight 在数组上向后迭代,保留另一个id和name值数组,用于检查原始数组中的每个对象 some 。如果找到匹配项,则将其删除。

一些非常方便,因为一旦找到匹配就会返回。

唯一的问题是它保留了副本的最后一个实例,你可能想要第一个。

var data  = [
             { id: 1, name: 'Amy', data: 'phone: 03492'},
             { id: 1, name: 'Donna', data: 'phone: 903489349'},
             { id: 2, name: 'Amy', data: 'address: Street 1'},
             { id: 1, name: 'Amy', data: 'address: Street 2'}
            ];

data.reduceRight(function(acc, v, i) {
  if (acc.some(function(obj){return v.name == obj.name && v.id == obj.id})) {
    data.splice(i, 1);
  } else {
    acc.push({id:v.id, name:v.name});
  }
  return acc;
}, []);

document.write(JSON.stringify(data).replace(/},{/g,'},<br>{'))

如果允许箭头功能,则测试变为:

if (acc.some(obj => v.name == obj.name && v.id == obj.id)) 

修改

由于您已经更改了问题,因此该功能需要进行少量调整,但效率会提高:

var data  = [
             { id: 1, name: 'Donna', data: 'phone: 903489349'},
             { id: 2, name: 'Amy', data: 'address: Street 1'},
             { id: 1, name: 'Amy', data: 'address: Street 2'}
            ];

var checkObj = { id: 1, name: 'Amy', data: 'phone: 03492'};

data.reduceRight(function(acc, obj, i) {
  if (obj.name == acc.name && obj.id == acc.id) {
    data.splice(i, 1)
  }
  return acc;
}, checkObj);

document.write(JSON.stringify(data).replace(/},{/g,'},<br> {'))

答案 4 :(得分:0)

我专注于一个就地编辑historyList对象的解决方案,因为这似乎是原始问题的要求。

var historyList = [
    { id: 1, name: 'Donna', data: 'phone: 903489349'},
    { id: 2, name: 'Amy', data: 'address: Street 1'},
    { id: 1, name: 'Amy', data: 'address: Street 2'}
];

var newHistoryObject = { id: 1, name: 'Amy', data: 'phone: 03492'};

for (var i = 0; i < historyList.length; i++) {
  if (historyList[i].id == newHistoryObject.id &&
      historyList[i].name == newHistoryObject.name) {
    historyList.splice(i--, 1);
  }
}

console.log(JSON.stringify(historyList));