【问题标题】:Find and remove objects in an array based on a key value in JavaScript基于 JavaScript 中的键值查找和删除数组中的对象
【发布时间】:2014-02-09 13:54:03
【问题描述】:

我一直在尝试几种方法来查找数组中的对象,其中 ID = var,如果找到,则从数组中删除该对象并返回新的对象数组。

数据:

[
    {"id":"88","name":"Lets go testing"},
    {"id":"99","name":"Have fun boys and girls"},
    {"id":"108","name":"You are awesome!"}
]

我可以使用 jQuery $grep 搜索数组;

var id = 88;

var result = $.grep(data, function(e){
     return e.id == id;
});

但是当 id == 88 时如何删除整个对象,并返回如下数据?

数据:

[
    {"id":"99", "name":"Have fun boys and girls"},
    {"id":"108", "name":"You are awesome!"}
]

【问题讨论】:

  • 使用slice 函数和一点for 循环怎么样?
  • 当然,但是,我写这个问题的原因是因为我被卡住了;)任何sn-ps?
  • 标题和问题文本似乎有冲突...建议使用两种完全不同的方法:A. 从数组中删除项目与 B. 创建一个新的过滤数组。

标签: javascript jquery arrays object


【解决方案1】:

如果你不使用 jQuery,这里有一个解决方案:

myArray = myArray.filter(function( obj ) {
  return obj.id !== id;
});

【讨论】:

  • 这比在父数组上执行findIndex() 然后splice(index, 1) 更好吗?
  • splice 会改变原始数组。使用过滤器,您可以选择。
  • 您可以使用以下方法将其减少为一行:myArr = myArray.filter(obj => obj.id !== id);
  • 更简洁的arr = arr.filter( obj => obj.id !== id);
  • 有人能解释一下'filter()'和'findIndex()+splice(index,1)'之间的时间复杂度差异吗
【解决方案2】:

我可以 grep 数组的 id,但是如何删除 id == 88 的整个对象

只需按相反的谓词过滤:

var data = $.grep(data, function(e){ 
     return e.id != id; 
});

【讨论】:

  • 这个答案为jQuery提供了最简洁和惯用的解决方案
  • 在你想删除所有 id=something 的项目的情况下……但使用 $.grep 时要小心,因为它会搜索整个数组,而对于长数组,它效率不高。有时你只需要通过给定的ID检查元素是否存在于数组中,那么最好使用另一种迭代方法;)
  • 这不会从列表中删除该对象
  • @ArunSivan slice 也不会删除任何内容。不知道你在做什么。如果您自己有特定问题,您可能想ask a new question
  • @Learner data.filter(e => !ids.includes(e.id))
【解决方案3】:

你可以简化这个,这里真的不需要使用 jQuery。

var id = 88;

for(var i = 0; i < data.length; i++) {
    if(data[i].id == id) {
        data.splice(i, 1);
        break;
    }
}

只需遍历列表,找到匹配的 id,拼接,然后 break 退出循环。

【讨论】:

  • +1,但你应该提到,这只会删除第一个匹配的项目。
  • ... 如果您需要删除每个匹配的项目,请使用 i=data.length; i &gt; 0; i-- 按相反顺序循环,不要使用 break
  • i = data.length 会破坏任何data[i],它应该类似于i=data.length -1 ; i &gt; -1; i--
【解决方案4】:

ES6/2015 中有一种新方法可以使用 findIndex 和数组展开运算符:

const index = data.findIndex(obj => obj.id === id);
const newData = [
    ...data.slice(0, index),
    ...data.slice(index + 1)
]

你可以像这样把它变成一个函数供以后重用:

function remove(array, key, value) {
    const index = array.findIndex(obj => obj[key] === value);
    return index >= 0 ? [
        ...array.slice(0, index),
        ...array.slice(index + 1)
    ] : array;
}

这样,您可以使用一种方法通过不同的键删除项目(如果没有符合条件的对象,则返回原始数组):

const newData = remove(data, "id", "88");
const newData2 = remove(data, "name", "You are awesome!");

或者你可以把它放在你的 Array.prototype 上:

Array.prototype.remove = function (key, value) {
    const index = this.findIndex(obj => obj[key] === value);
    return index >= 0 ? [
        ...this.slice(0, index),
        ...this.slice(index + 1)
    ] : this;
};

并以这种方式使用它:

const newData = data.remove("id", "88");
const newData2 = data.remove("name", "You are awesome!");

【讨论】:

  • findIndex() 真的很棒! ?
  • 如果你有多个键和值怎么办?
【解决方案5】:
var items = [
  {"id":"88","name":"Lets go testing"},
  {"id":"99","name":"Have fun boys and girls"},
  {"id":"108","name":"You are awesome!"}
];

如果您使用的是 jQuery,请像这样使用jQuery.grep

items = $.grep(items, function(item) { 
  return item.id !== '88';
});
// items => [{ id: "99" }, { id: "108" }]

使用 ES5 Array.prototype.filter:

items = items.filter(function(item) { 
  return item.id !== '88'; 
});
// items => [{ id: "99" }, { id: "108" }]

【讨论】:

  • 不!不要使用jQuery map 作为过滤器。
  • 同意!您使用 grep 的解决方案是使用 jQuery 的正确解决方案。
【解决方案6】:

假设 id 是唯一的,您只需要删除一个元素 splice 就可以了:

var data = [
  {"id":"88","name":"Lets go testing"},
  {"id":"99","name":"Have fun boys and girls"},
  {"id":"108","name":"You are awesome!"}
],
id = 88;

console.table(data);

$.each(data, function(i, el){
  if (this.id == id){
    data.splice(i, 1);
  }
});

console.table(data);

【讨论】:

  • 你的回调函数中的元素是向后的。应该是each(data,function(idx,ele)。稍后我会为我浪费的 30 分钟向你收费:)
  • 糟糕。在这种情况下,我至少能做的是更新我的答案。我对你浪费了 30 分钟的生命感到非常难过。
【解决方案7】:

原生ES6解决方案:

const pos = data.findIndex(el => el.id === ID_TO_REMOVE);
if (pos >= 0)
    data.splice(pos, 1);

如果你确定元素在数组中:

data.splice(data.findIndex(el => el.id === ID_TO_REMOVE), 1);

原型:

Array.prototype.removeByProp = function(prop,val) {
    const pos = this.findIndex(x => x[prop] === val);
    if (pos >= 0)
        return this.splice(pos, 1);
};

// usage:
ar.removeByProp('id', ID_TO_REMOVE);

http://jsfiddle.net/oriadam/72kgprw5/

注意:这会就地删除项目。如果您需要一个新数组,请使用filter,如前面的答案中所述。

【讨论】:

  • 找不到id的情况你不处理。在这种情况下,您的解决方案会删除数组的元素
【解决方案8】:

也许你正在寻找$.grep()函数:

arr = [
  {"id":"88","name":"Lets go testing"},
  {"id":"99","name":"Have fun boys and girls"},
  {"id":"108","name":"You are awesome!"}
];

id = 88;
arr = $.grep(arr, function(data, index) {
   return data.id != id
});

【讨论】:

    【解决方案9】:
    const data = [
        {"id":"88","name":"Lets go testing"},
        {"id":"99","name":"Have fun boys and girls"},
        {"id":"108","name":"You are awesome!"}
    ];
    

    这里我们得到id值为“88”的对象的索引

    const index = data.findIndex(item => item.id === "88");
    console.log(index); // 0
    

    我们使用拼接函数从数据数组中删除指定的对象

    data.splice(index,1);
    console.log(data); // [{"id":"99","name":"Have fun boys and girls"},{"id":"108","name":"You are awesome!"}]
    

    【讨论】:

      【解决方案10】:
      Array.prototype.removeAt = function(id) {
          for (var item in this) {
              if (this[item].id == id) {
                  this.splice(item, 1);
                  return true;
              }
          }
          return false;
      }
      

      这应该可以解决问题,jsfiddle

      【讨论】:

        【解决方案11】:

        sift 是一个强大的收集过滤器,适用于此类操作和更高级的操作。它在浏览器的客户端或Node.js 的服务器端工作。

        var collection = [
            {"id":"88",  "name":"Lets go testing"},
            {"id":"99",  "name":"Have fun boys and girls"},
            {"id":"108", "name":"You are awesome!"}
        ];
        var sifted = sift({id: {$not: 88}}, collection);
        

        支持$in$nin$exists$gte$gt$lte$lt$eq$ne$all4等过滤器,$and$or$nor$not$size$type,和$regex,并努力与MongoDB集合过滤API兼容。

        【讨论】:

        • 为什么没有upwotes?如果这个东西写得正确并且没有可怕的错误,它应该是非常有用的。
        【解决方案12】:

        我同意前面的答案。如果您想通过 id 查找对象并将其删除,一个简单的方法就像下面的代码:

        var obj = JSON.parse(data);
        var newObj = obj.filter(item => item.Id != 88);
        

        【讨论】:

          【解决方案13】:

          如果您测试严格相等,请确保将对象 ID 强制转换为整数:

          var result = $.grep(data, function(e, i) { 
            return +e.id !== id;
          });
          

          Demo

          【讨论】:

            【解决方案14】:

            如果你使用Underscore.js,很容易根据一个键删除一个对象。

            例子:

              var temp1=[{id:1,name:"safeer"},  // Temporary array
                         {id:2,name:"jon"},
                         {id:3,name:"James"},
                         {id:4,name:"deepak"},
                         {id:5,name:"ajmal"}];
            
              var id = _.pluck(temp1,'id'); // Get id array from temp1
              var ids=[2,5,10];             // ids to be removed
              var bool_ids=[];
              _.each(ids,function(val){
                 bool_ids[val]=true;
              });
              _.filter(temp1,function(val){
                 return !bool_ids[val.id];
              });
            

            【讨论】:

              猜你喜欢
              • 2023-03-02
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多