根据对象属性删除数组元素


270

我有一个像这样的对象数组:

var myArray = [
    {field: 'id', operator: 'eq', value: id}, 
    {field: 'cStatus', operator: 'eq', value: cStatus}, 
    {field: 'money', operator: 'eq', value: money}
];

如何根据其属性删除特定的?

例如,我将如何删除以'money'作为字段属性的数组对象?

Answers:


382

一种可能性:

myArray = myArray.filter(function( obj ) {
    return obj.field !== 'money';
});

请注意,将filter创建一个新数组。尽管您myArray使用新的引用更新了原始变量,但其他任何引用原始数组的变量都不会获取过滤后的数据。请谨慎使用。


6
请注意,filter()仅适用于Internet Explorer 9+
jessegavin 2013年

确实是@jessegavin。我应该提到,有很多不错的es5填充程序库,它们可以模拟功能(以防万一您想支持旧版浏览器)
jAndy 2013年

3
filter()创建一个新的数组,如果您能够重新分配该变量并且知道没有其他代码区域可以引用该变量,那将是一个很好的选择。如果您特别需要修改原始数组对象,则此方法将无效。
Brian Glick 2014年

2
如果数组是树结构,然后arDeleteOperationArray = [{“” id“:3.1,” name“:” test 3.1“,” activityDetails“:[{” id“:22,” name“:” test 3.1“}, {“ id”:23,“ name”:“更改的测试23”}]}],我想删除id:23
forgottofly

@forgottofly优点-答案仅在有限的情况下有效。您找到问题的答案了吗?
JackTheKnife

88

遍历数组,然后splice删除不需要的数组。为了更容易使用,请向后迭代,这样您就不必考虑数组的实时特性:

for (var i = myArray.length - 1; i >= 0; --i) {
    if (myArray[i].field == "money") {
        myArray.splice(i,1);
    }
}

3
阵列的实时特性是什么意思?@Neit the Dark Absol
sisimh 2015年

29
@sisimh他的意思是,如果您通过使用数组的长度作为迭代逻辑的一部分来迭代数组,并且由于其元素已删除或添加而更改了数组的长度,则可能导致数组末尾运行或不对数组进行操作数组中的每个项目。向后退使得它朝静态0索引而不是移动长度工作的可能性大大降低。
克洛尔斯2015年

2
如果数组是树结构,然后arDeleteOperationArray = [{“” id“:3.1,” name“:” test 3.1“,” activityDetails“:[{” id“:22,” name“:” test 3.1“}, {“ id”:23,“ name”:“更改的测试23”}]}],我想删除id:23
forgottofly

有点明显,但是如果您只希望删除单个唯一元素,则可以在“ if”语句中添加一个中断以提高性能,从而使循环不必遍历数组的其余部分。
帕特里克·博尔科维奇

@Klors感谢您的解释。总是像答案一样总是向后读取数组,这很好吗?
kittu

37

假设您要通过第二个对象的field属性来删除它。

使用ES6,就这么简单。

myArray.splice(myArray.findIndex(item => item.field === "cStatus"), 1)

6
我试过了,但是您的代码“已过滤”并仅显示了第三项,而不是从OP的数组中“删除”第三项。
Compaq LE2202x '18

1
@ CompaqLE2202x 2年后,它对您可能已经很明显了,但是对于将来的开发人员:splice更改原始数组,因此您获得的值是被删除的项目,但是如果您下次查看myArray该项目,将会丢失。
David Mulder

16

您可以使用lodash的findIndex获取特定元素的索引,然后使用该元素进行拼接。

myArray.splice(_.findIndex(myArray, function(item) {
    return item.value === 'money';
}), 1);

更新资料

您还可以使用ES6的findIndex()

findIndex()方法返回满足提供的测试功能的数组中第一个元素的索引。否则返回-1。

myArray.splice(myArray.findIndex(myArray, function(item) {
    return item.value === 'money';
}), 1);

什么是树结构数组?
forgottofly

@forgottofly树结构?我认为myArray这是一组对象。
斯里达尔(Sridhar)

3
如果数组是树结构,该怎么办var beforeDeleteOperationArray = [{“ id”:3.1,“ name”:“ test 3.1”,“ activityDetails”:[{“ id”:22,“ name”:“ test 3.1”}, {“ id”:23,“ name”:“更改的测试23”}]}],我想删除id:23
forgottofly

9

这是使用jQuery grep的另一个选项。true作为第三个参数传递,以确保grep删除与您的函数匹配的项目。

users = $.grep(users, function(el, idx) {return el.field == "money"}, true)

如果您已经在使用jQuery,则不需要填充程序,这与使用相比可能会有用Array.filter



3

如果您不使用jQuery,则下面是代码。演示版

var myArray = [
    {field: 'id', operator: 'eq', value: 'id'}, 
    {field: 'cStatus', operator: 'eq', value: 'cStatus'}, 
    {field: 'money', operator: 'eq', value: 'money'}
];

alert(myArray.length);

for(var i=0 ; i<myArray.length; i++)
{
    if(myArray[i].value=='money')
        myArray.splice(i);
}

alert(myArray.length);

您还可以使用下划线库,该库具有很多功能。

Underscore是JavaScript实用程序带库,可提供许多功能性编程支持


5
这是一个非常危险的示例,无法在网络上使用。它仅适用于示例数据,不适用于其他任何数据。splice(i)意味着它将删除数组中从值是金钱的第一个实例开始和之后的所有元素,这些实例根本无法满足op的要求。如果我们将其更改为splice(i,1),它仍然是不正确的,因为它不会评估下一个顺序项(您也必须减少i)。这就是为什么您应该向后处理数组中的remove操作,以便删除项不会更改下一个要处理的项的索引
克里斯·谢勒

3
var myArray = [
    {field: 'id', operator: 'eq', value: id}, 
    {field: 'cStatus', operator: 'eq', value: cStatus}, 
    {field: 'money', operator: 'eq', value: money}
];
console.log(myArray.length); //3
myArray = $.grep(myArray, function(element, index){return element.field == "money"}, true);
console.log(myArray.length); //2

元素是数组中的一个对象。第三个参数true意味着将返回使您的功能逻辑失败的元素数组,false意味着将返回使您的功能逻辑失败的元素数组。


3

使用lodash库:

var myArray = [
    {field: 'id', operator: 'eq', value: 'id'}, 
    {field: 'cStatus', operator: 'eq', value: 'cStatus'}, 
    {field: 'money', operator: 'eq', value: 'money'}
];
var newArray = _.remove(myArray, function(n) {
  return n.value === 'money';;
});
console.log('Array');
console.log(myArray);
console.log('New Array');
console.log(newArray);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.5/lodash.js"></script>


2

基于上面的一些评论,该代码给出了如何根据键名和键值删除对象的代码

 var items = [ 
  { "id": 3.1, "name": "test 3.1"}, 
  { "id": 22, "name": "test 3.1" }, 
  { "id": 23, "name": "changed test 23" } 
  ]

    function removeByKey(array, params){
      array.some(function(item, index) {
        return (array[index][params.key] === params.value) ? !!(array.splice(index, 1)) : false;
      });
      return array;
    }

    var removed = removeByKey(items, {
      key: 'id',
      value: 23
    });

    console.log(removed);

1

jAndy的解决方案可能是最好的,但是如果您不能依赖过滤器,则可以执行以下操作:

var myArray = [
    {field: 'id', operator: 'eq', value: 'id'}, 
    {field: 'cStatus', operator: 'eq', value: 'cStatus'}, 
    {field: 'money', operator: 'eq', value: "money"}
];

myArray.remove_key = function(key){
    var i = 0, 
        keyval = null;
    for( ; i < this.length; i++){
        if(this[i].field == key){
            keyval = this.splice(i, 1);
            break;
        }
    }
    return keyval;
}

1
为什么我不能依靠filter()?
imperium2335

2
由于它是JavaScript 1.6的一部分,因此IE8及更低版本或更低版本的浏览器不支持。
罗伯M.13年

-1

使用lodash库很简单

_.remove(myArray , { field: 'money' });
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.