从对象数组中删除对象

45

我有一个对象数组:

[{"value":"14","label":"7"},{"value":"14","label":"7"},{"value":"18","label":"7"}]

我该如何删除这个项目{"value":"14","label":"7"},从而产生新数组:

 [{"value":"14","label":"7"},{"value":"18","label":"7"}]

?


你想要删除重复项吗? - bhantol
你需要更具体地说明用于确定是否应该移除一个项目的标准。 - JAAulde
如果您想要删除重复的对象,请参考此线程:https://dev59.com/U3E95IYBdhLWcg3wp_kg - Suchit kumar
9个回答

92

40

使用对象标识的解决方案

如果您有对象标识而不仅仅是对象相等性(即,您想从数组中删除特定对象,而不仅仅是包含与现有对象相同数据的对象),则可以使用splice和indexOf非常简单地完成此操作:

a = {x:1}
b = {x:2}
arr = [a,b]

假设你想要删除b:

arr.splice(
  arr.indexOf(b), 1
);

等式解决方案

问题并没有明确说明我们是在处理身份识别还是相等性。如果你有相等性(包含相同内容、外观相同但实际上不是同一个对象的两个对象),你就需要一个小比较函数,我们可以将它传递给findIndex方法。

a = {x: 1};
b = {x: 2};
arr = [a, b];

现在我们想要移除c,它等于a但并非同一对象:

c = {x: 1}

index = arr.findIndex(
  (i) => i.x === c.x
)

if (index !== -1) {
  arr.splice(
    index, 1
  );
}    

需要注意的是,我将一个ES6类型的lambda函数作为第一个参数传递给findIndex。

除非您只面向最新的浏览器,否则您可能需要使用像Babel这样的转译器来使用此解决方案。

具有不变性的解决方案

如果您关心不可变性,并且想要返回一个新数组,则可以使用filter来实现:

a = {x: 1};
b = {x: 2};
arr = [a, b];

让我们保留除了a以外的所有内容:

newArr = arr.filter((x) => x != a)

16

尝试:

var ar = [{"value":"14","label":"7"},{"value":"14","label":"7"},{"value":"18","label":"7"}];

for(var i=0; i < ar.length; i++) {
   if(ar[i].value == "14" && ar[i].label == "7")
   {
      ar.splice(i,1);
   }
}

演示


但这将在数组中创建空值 (也称为 undefined)。即 [undefined, undefined, {...}] - user602271
也许你在 splice 后忘记了 i--。 - Tazo leladze

3
如果您不想改变数组,只需使用筛选方法Array.prototype.filter()array.filter((i)=> i != "b");

1

我将创建一个新的数组...

var original = [{"value":"14","label":"7"},{"value":"14","label":"7"},{"value":"18","label":"7"}]

var result = [];

for (var i = 0, l = original.length; i < l; i++) { // Traverse the whole array
  var current = original[i];
  if (! (current.value == 14 && current.label == 7) ) {
    // It doesn't match the criteria, so add it to result
    result.push( current );
  }
}

编辑:我再次阅读了您的问题。您只想删除第一个元素吗?那么使用 slice 来获取数组的一部分。

var result = original.slice(1, original.length)

或者 splice
original.splice(0,1); // Remove one element from index 0.

1

以下是一种不需要“创建新数组”或使用外部库的方法。请注意,这只会删除找到的第一个实例,而不是重复项,正如您问题示例中所述。

// Array to search
var arr = [{"value":"14","label":"7"},{"value":"14","label":"7"},{"value":"18","label":"7"}];

// Object to remove from arr
var remove = {"value":"14","label":"7"};

// Function to determine if two objects are equal by comparing
// their value and label properties
var isEqual = function(o1, o2) {
    return o1 === o2 || 
        (o1 != null && o2 != null && 
         o1.value === o2.value &&
         o1.label === o2.label);
};

// Iterate through array and determine if remove is in arr
var found = false;
var i;
for(i = 0; i < arr.length; ++i) {
    if(isEqual(arr[i], remove)) {
        found = true;
        break;
    }
}

if(found) {
    // Found remove in arr, remove it
    arr.splice(i, 1);
}

演示


1
使用ES6方法:
const objIndex = objs.findIndex(o => o.value === '14' && o.label === '7')

if(objIndex > -1) {
  objs.slice(objIndex, 1)
}

找到索引就赢了!不过我觉得你想用“splice”。 - Ti Hausmann
在切片中,“原始数组不会被修改”。 - Craig van Tonder

0
你需要保留重复的对象吗?
使用underscoreJS。
var oldarray = [{"value":"14","label":"7"},{"value":"14","label":"7"},{"value":"18","label":"7"}]
var newarray = _.reject(oldarray, function(o) { 
  return o == {"value":"14","label":"7"}; 
});

3
你的比较结果将始终为“false”(没有对象与另一个对象“==”)。 - Noah Freitas

0
function removeDuplicateObject (arr) {
  let temp = arr.map((item) => {
    return JSON.stringify(item);
  });
  temp = Array.from(new Set(temp));
  return temp.map((item) => {
    return JSON.parse(item);
  });
}

然后 removeDuplicateObject(你的数组)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接