通过对象属性从数组中删除对象
var listToDelete = ['abc', 'efg']; var arrayOfObjects = [{id:'abc',name:'oh'}, // delete me {id:'efg',name:'em'}, // delete me {id:'hij',name:'ge'}] // all that should remain
如何通过匹配对象属性从数组中删除对象?
请只有原生的JavaScript。
使用拼接时遇到问题,因为每次删除都会减less长度。 在信号指数上使用克隆和拼接仍然留下长度缩短的问题。
我假设你使用这种splice
?
for(var i = 0; i < arrayOfObjects.length; i++) { var obj = arrayOfObjects[i]; if(listToDelete.indexOf(obj.id) !== -1) { arrayOfObjects.splice(i, 1); } }
所有你需要做的就是减lessi
下一次,然后:
for(var i = 0; i < arrayOfObjects.length; i++) { var obj = arrayOfObjects[i]; if(listToDelete.indexOf(obj.id) !== -1) { arrayOfObjects.splice(i, 1); i--; } }
你当然也可以向后循环 – 你的select。 最后,有filter
,给予ES5arrays支持或垫片:
var newArray = arrayOfObjects.filter(function(obj) { return listToDelete.indexOf(obj.id) === -1; });
ES6:
const toDelete = new Set(['abc', 'efg']); const newArray = arrayOfObjects.filter(obj => !toDelete.has(obj.id));
您可以通过其中一个属性删除一个项目,而无需使用任何第三方库:
var removeIndex = array.map(function(item) { return item.id; }) .indexOf("abc"); ~removeIndex && array.splice(removeIndex, 1);
findIndex适用于现代浏览器:
var myArr = [{id:'a'},{id:'myid'},{id:'c'}]; var index = arr.findIndex(function(o){ return o.id === 'myid'; }) if (index !== -1) myArr.splice(index, 1);
如果你只是想从现有的数组中删除它,而不是创build一个新的,请尝试:
var items = [{Id: 1},{Id: 2},{Id: 3}]; items.splice(_.indexOf(items, _.find(items, function (item) { return item.Id === 2; })), 1);
如果你想修改现有的数组本身,那么我们必须使用拼接 。 下面是使用下划线/ lodash的findWhere的一些好的/可读的方法:
var items= [{id:'abc',name:'oh'}, // delete me {id:'efg',name:'em'}, {id:'hij',name:'ge'}]; items.splice(_.indexOf(items, _.findWhere(items, { id : "abc"})), 1);
通过递减i
来避免这个问题来反向循环:
for (var i = arrayOfObjects.length - 1; i >= 0; i--) { var obj = arrayOfObjects[i]; if (listToDelete.indexOf(obj.id) !== -1) { arrayOfObjects.splice(i, 1); } }
或者使用filter
:
var newArray = arrayOfObjects.filter(function(obj) { return listToDelete.indexOf(obj.id) === -1; });
请只有原生的JavaScript。
作为一种替代scheme,使用ECMAScript 5的更“function”的解决scheme,您可以使用:
var listToDelete = ['abc', 'efg']; var arrayOfObjects = [{id:'abc',name:'oh'}, // delete me {id:'efg',name:'em'}, // delete me {id:'hij',name:'ge'}]; // all that should remain arrayOfObjects.reduceRight(function(acc, obj, idx) { if (listToDelete.indexOf(obj.id) > -1) arrayOfObjects.splice(idx,1); }, 0); // initial value set to avoid issues with the first item and // when the array is empty. console.log(arrayOfObjects); [ { id: 'hij', name: 'ge' } ]
根据ECMA-262中“Array.prototype.reduceRight”的定义 :
reduceRight不会直接改变它被调用的对象,但是对象可能会被callbackfn的调用所突变 。
所以这是reduceRight
的有效用法。
如果你喜欢简短和自我描述的参数,或者你不想使用splice
并去一个简单的filter,或者如果你只是一个像我这样的SQL人:
function removeFromArrayOfHash(p_array_of_hash, p_key, p_value_to_remove){ return p_array_of_hash.filter((l_cur_row) => {return l_cur_row[p_key] != p_value_to_remove}); }
还有一个示例用法:
l_test_arr = [ { post_id: 1, post_content: "Hey I am the first hash with id 1" }, { post_id: 2, post_content: "This is item 2" }, { post_id: 1, post_content: "And I am the second hash with id 1" }, { post_id: 3, post_content: "This is item 3" }, ]; l_test_arr = removeFromArrayOfHash(l_test_arr, "post_id", 2); // gives both of the post_id 1 hashes and the post_id 3 l_test_arr = removeFromArrayOfHash(l_test_arr, "post_id", 1); // gives only post_id 3 (since 1 was removed in previous line)