使用普通for循环删除重复的对象数组

时间:2016-11-18 16:22:40

标签: javascript arrays json loops for-loop

我知道有一个快捷方式,比如使用loadash< uniq,但我尝试使用native for循环删除重复的对象数组。

var json = [
{name:"james"},
{name:"james_x"},
{name:"jame"},
{name:"james_x"}
]

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

console.log(json);

https://jsfiddle.net/8wwnvzoc/

我真的想知道错误。

4 个答案:

答案 0 :(得分:1)

在迭代数组时,您不应该修改数组。这将导致意外的行为。我建议您构建一个索引数组,以便在完全通过数组后删除然后删除它们。

要修复算法,您需要跟踪所有您已经看过的名称。您可以使用ES6设置。

var json = [
{name:"james"},
{name:"james_x"},
{name:"jame"},
{name:"james_x"}
]
var indicesToRemove = [];
var seen = new Set();    

for(var i = 0;i<json.length;i++){
   if (seen.has(json[i].name)) {
     indicesToRemove.push(i) 
   } else {
     seen.add(json[i].name);
   } 
}

for(index of indicesToRemove.reverse()) {
    // iterating backwards to prevent indices changing on us...
    json.splice(index,index);
}
console.log(json);

答案 1 :(得分:1)

尝试对数组进行排序,然后循环遍历它:

var json = [
{name:"james"},
{name:"james_x"},
{name:"jame"},
{name:"james_x"}
]

json = json.sort(function(a, b){a=a.name;b=b.name;return a<b?-1:a>b?1:0});

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

console.log(json);

然后,相等的值将彼此接近,因此您的算法将按预期工作...

编辑:

一种可能更好的方法,但不使用循环:

var json = [
{name:"james"},
{name:"james_x"},
{name:"jame"},
{name:"james_x"}
]

json = json
    .sort(function(a, b){a=a.name;b=b.name;return a<b?-1:a>b?1:0})
    .reduce(function(a, b){var n=a.length;if(n===0||a[n-1].name!==b.name)a[n]=b;return a},[]);

console.log(json);

答案 2 :(得分:0)

你可以这样做:

var json = [{
   name: "james"
  }, {
  name: "james_x"
  }, {
  name: "jame"
  }, {
  name: "james_x"
  }]

const unique = []

json.forEach(function(item) {
    var existingName = unique.find(function(name) { return name.name === item.name})
    !existingName ? unique.push(item) : null
})

console.log(unique)

答案 3 :(得分:0)

在测试重复时,您没有检查所有其他项目。进一步你在迭代它时修改数组 - 这可能会崩溃。

var json = [
  { name:"james" },
  { name:"james" },
  { name:"james_x" },
  { name:"james_x" },
  { name:"james_x" },
  { name:"jame" },
  { name:"james_x" },
  { name:"jame" },
];

var i = 0,
    index = { /* track what we've seen already */ },
    current;

while (i < json.length) {
  current = json[i].name;

  // check if the name is in index
  if (current in index) {
    // it is, remove it from the array
    json.splice(i, 1);
  } else {
    // not in index, leave it untouched and add it to the index
    // by defining a key in "index" with arbitrary value
    index[current] = true;
    // only step forward when indexing, not when removing
    i++;
  }
}

增量仅限于索引分支,因为如果算法也是重复的,则算法会意外跳过下一个项目(以下项目将向左/向上移动)。

查看进度(第2列是第1列的以下迭代步骤):

在两个分支中递增时:

1            1
2            2
3            3
2 <= dupe    2 
2            2 <= accidentally incremented
2            4    missed the previous item
4

正确增量:

1            1
2            2
3            3
2 <= dupe    2 <= not incremented, all OK
2            2
2            4
4