Javascript 如何删除阵列中重复对象的两个实例
我有一个对象数组。我试图找到重复的对象,然后删除该对象的两个实例 现在我正在使用这种方法:Javascript 如何删除阵列中重复对象的两个实例,javascript,arrays,object,Javascript,Arrays,Object,我有一个对象数组。我试图找到重复的对象,然后删除该对象的两个实例 现在我正在使用这种方法: function checkForDups(data){ for(var i = 0; i < data.length; i++){ for(var j = i+1; j < data.length; j++){ if(data[j].number === data[i].number){ data.splice(j,1);
function checkForDups(data){
for(var i = 0; i < data.length; i++){
for(var j = i+1; j < data.length; j++){
if(data[j].number === data[i].number){
data.splice(j,1);
data.splice(i,1);
}
}
}
return data;
}
功能检查(数据){
对于(变量i=0;i
我认为问题在于,它只检查索引大于当前位置的重复项。这意味着不会检查阵列中“在其后面”的对象是否存在重复。目前,我通过这个函数运行数组几次,以获得所需的结果。然而,这显然是非常低效的。我怎样才能更有效地实现我想要的结果
我认为问题在于,它只检查索引大于当前位置的重复项。这意味着不会检查阵列中“在其后面”的对象是否存在重复
不,这是一个简单的优化,因为等式关系的对称性。通过向前搜索并删除前面的所有重复项,任何当前项都不能是前一项的重复项,否则它将被删除
但是,有些事情你没有注意到:
- 从阵列中拼接(删除)项目时,将移动所有后续项目,并且阵列将更改其长度。要真正检查数组中的所有项,在删除时需要减少(或:不增加)计数器变量,以便访问与已删除项位于同一位置的新项(刚删除的位置需要重新访问)
- 在找到重复项后,您可能希望
中断内部循环,否则您将比较并删除完全不同的项
- 您尚未明确当数组中有两个以上相同排序的重复项时,算法应该做什么。当他们的号码是奇数时留下一个?感谢您的评论。
要删除所有现有的重复项,您需要继续搜索,但不得立即删除
th元素,否则您将没有任何东西可与FutureOn进行比较,或者您甚至可能多次删除i
th项(请参见#2)i
function removeAllDups(data) {
// leaves only items in the array that appeared a single time
// removes everything whose .number can be found multiple times
for (var i = 0; i < data.length; i++) {
var found = false,
num = data[i].number;
for (var j = i+1; j < data.length; j++) {
if (data[j].number === num) {
found = true;
data.splice(j--, 1);
}
}
if (found) {
data.splice(i--, 1);
}
}
return data;
}
函数removeAllDups(数据){
//仅在数组中保留一次出现的项
//删除可以多次找到其.number的所有内容
对于(变量i=0;i
这里有一个替代实现。这仅使用两次通过阵列,并在>2的情况下删除所有重复:
请注意,这假设支持ES5方法-Array#some
,函数#bind
。如果您需要支持较旧的浏览器,ES5垫片或下划线库将符合要求。您可以使用:
例子
您可以试试。您能发布一个示例数组来产生意外的结果吗?请注意,这只适用于基本值(通常:所有可以转换为不同字符串的内容)。OP通过其
.number
属性测试(对象)项的相等性。当发现重复项时,我希望它删除该重复项的两个实例。例如,假设我有一个数组,看起来像code
[{name:“foo”,number:1},{name:“bar”,number:2},{name:“foo”,number:1}]code
我只想让它返回code
[{name:“bar”,number:2}]code
对不起,我刚刚重读了你的回答,意识到我对你的最后一点反应不正确。您刚刚让我意识到,我的主要问题之一是,在某些情况下,我有3个对象实例,但没有实现任何解释。如果有3个实例,我希望所有实例都被删除。非常感谢,这非常有效!但是,我不完全理解为什么在拼接方法中更改j和I的值。似乎合乎逻辑的是,您需要在索引处拼接数据[j].number==num的项,然后需要减少i和j,以考虑已删除的索引。是的,这就是所做的。请注意,我使用了--
作为后缀运算符,即splice()
将传递原始值。啊,我明白了。再次感谢您的回复!这很有帮助,也很有见地。
function removeDupes(arr, test) {
test = test || function(a, b) { return a === b; };
function find(cache, element) {
return cache.some(test.bind(null, element));
}
var seen = [];
var dupes = [];
var len = arr.length;
var x;
var current;
// First pass - find dupes
for (x = 0; x < len; x++) {
current = arr[x];
if (find(seen, current)) {
dupes.push(current);
} else {
seen.push(current);
}
}
// Second pass: remove dupes. Reverse iteration saves headaches here
for (x = len - 1; x >= 0; x--) {
current = arr[x];
if (find(dupes, current)) {
arr.splice(x, 1);
}
}
}
removeDupes(arr, function(a, b) {
return a.number == b.number;
});
function checkForDups(data) {
return (
_.map(
_.filter(
_.pairs(
_.countBy(data)
), function(v) {return v[1] == 1}
), function(v) {return ~~v[0]}
)
)
}
>> console.log(checkForDups([0,1,2,3,0,1,0,4]))
[2, 3, 4]