根据对象的某些属性的数组,从数组中删除对象

22

我有一个对象数组(objList),每个对象都有一个"id"属性。

我有一个字符串数组(idsToRemove),表示要从objList中删除的对象的ID。

我找到了一些解决方案,但我担心它很慢,特别是对于具有许多属性的大型对象列表。是否有更有效的方法来完成这个任务?

var idsToRemove = ["3", "1"];
var objList = [{
    id: "1",
    name: "aaa"
  },
  {
    id: "2",
    name: "bbb"
  },
  {
    id: "3",
    name: "ccc"
  }
];

for (var i = 0, len = idsToRemove.length; i < len; i++) {
  objList = objList.filter(o => o.id != idsToRemove[i]);
}

console.log(objList);

4个回答

37
idsToRemove转换为一个Set,这样您就可以使用Set.prototype.hasO(1)操作),并只对objList进行一次.filter,使得总体复杂度为O(n)(并且只迭代可能很大的objList一次):

var idsToRemove = ["3", "1"];
var objList = [{
    id: "1",
    name: "aaa"
  },
  {
    id: "2",
    name: "bbb"
  },
  {
    id: "3",
    name: "ccc"
  }
];

const set = new Set(idsToRemove);
const filtered = objList.filter(({ id }) => !set.has(id));
console.log(filtered);
请注意,使用 Array.prototype.includesArray.prototype.indexOf 操作的时间复杂度为 O(N),而不是 O(1),因此如果您使用它们而不是 Set,可能需要更长的时间。

不确定 Set.has 的时间复杂度是否为 O(1) 是正确的。如果它是正确的,请回答这个问题。https://dev59.com/f1MI5IYBdhLWcg3w5v0N - Charlie
这不取决于数组的大小吗?如果数组很小,直接遍历它不是比创建一个新的内存副本然后访问它更好吗? - Orelsanpls
1
你是对的,如果idsToRemove只有很少数量的元素,使用Set并不能提供多大的好处。 - CertainPerformance
你能解释一下你的语法和这个语法之间的区别吗: const filtered = objList.filter(o => !set.has(o.id)); - Dalibor
1
@Dalibor 我的版本在参数列表中使用了解构赋值,而那个版本没有。如果一个函数不需要整个对象,而只需要其中一个(或一些)属性,我喜欢立即提取该属性,而不必保留整个对象 - 但两种选项都可以正常工作。 - CertainPerformance

4
您可以使用 Array.includes 方法检查给定数组中是否存在给定字符串,并将其与 Array.filter 方法结合使用。

const idsToRemove = ['3', '1'];

const objList = [{
    id: '1',
    name: 'aaa',
  },
  {
    id: '2',
    name: 'bbb',
  },
  {
    id: '3',
    name: 'ccc',
  },
];

const filteredObjList = objList.filter(x => !idsToRemove.includes(x.id));

console.log(filteredObjList);


3

1

Simply use Array.filter()

const idsToRemove = ['3', '1'];

const objList = [{
    id: '1',
    name: 'aaa',
  },
  {
    id: '2',
    name: 'bbb',
  },
  {
    id: '3',
    name: 'ccc',
  }
];

const res = objList.filter(value => !idsToRemove.includes(value.id));

console.log("result",res);


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