Javascript 按对象属性从数组中删除对象
如何通过匹配对象属性从数组中删除对象 请只使用本机JavaScript 我在使用剪接时遇到问题,因为每次删除时长度都会减少。Javascript 按对象属性从数组中删除对象,javascript,Javascript,如何通过匹配对象属性从数组中删除对象 请只使用本机JavaScript 我在使用剪接时遇到问题,因为每次删除时长度都会减少。 在原始索引上使用克隆和剪接仍然会给您带来长度递减的问题。我想您使用了splice类似的东西 var listToDelete = ['abc', 'efg']; var arrayOfObjects = [{id:'abc',name:'oh'}, // delete me {id:'efg',name:'em'}, // d
在原始索引上使用克隆和剪接仍然会给您带来长度递减的问题。我想您使用了
splice
类似的东西
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
为了避免线性时间删除,可以在数组上写入要保留的数组元素:
for (var i = 0; i < arrayOfObjects.length; i++) {
var obj = arrayOfObjects[i];
if (listToDelete.indexOf(obj.id) !== -1) {
arrayOfObjects.splice(i, 1);
i--;
}
}
var-end=0;
对于(变量i=0;i
为了避免现代运行时中的线性时间查找,您可以使用哈希集:
var end = 0;
for (var i = 0; i < arrayOfObjects.length; i++) {
var obj = arrayOfObjects[i];
if (listToDelete.indexOf(obj.id) === -1) {
arrayOfObjects[end++] = obj;
}
}
arrayOfObjects.length = end;
const setToDelete=新集合(listToDelete);
设end=0;
for(设i=0;i
它可以被包装在一个漂亮的函数中:
constfilteringplace=(数组,谓词)=>{
设end=0;
for(设i=0;i!toDelete.has(obj.id));
console.log(arrayOfObjects)代码>如果您只是想将其从现有阵列中删除,而不是创建新阵列,请尝试:
const setToDelete = new Set(listToDelete);
let end = 0;
for (let i = 0; i < arrayOfObjects.length; i++) {
const obj = arrayOfObjects[i];
if (setToDelete.has(obj.id)) {
arrayOfObjects[end++] = obj;
}
}
arrayOfObjects.length = end;
加上lodash/下划线:
如果要修改现有阵列本身,则必须使用拼接。下面是使用下划线/lodash的findWhere的更好/可读的方法:
var items = [{Id: 1},{Id: 2},{Id: 3}];
items.splice(_.indexOf(items, _.find(items, function (item) { return item.Id === 2; })), 1);
ES5或以上
(不带lodash/下划线)
对于ES5以后的版本,我们在数组上有了findIndex
方法,因此在没有lodash/下划线的情况下更容易实现
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);
(几乎所有现代浏览器都支持ES5)
,并通过减小i
来反向循环,以避免出现问题:
items.splice(items.findIndex(function(i){
return i.id === "abc";
}), 1);
或使用:
您可以通过项目的属性之一删除项目,而无需使用任何第三方LIB,如下所示:
var newArray = arrayOfObjects.filter(function(obj) {
return listToDelete.indexOf(obj.id) === -1;
});
请只使用本机JavaScript
作为另一种更具“功能性”的解决方案,您可以使用ECMAScript 5:
var removeIndex = array.map(item => item.id).indexOf("abc");
~removeIndex && array.splice(removeIndex, 1);
根据:
reduceRight不会直接改变调用它的对象,但是调用callbackfn会改变该对象
因此,这是reduceRight
的有效用法,findIndex适用于现代浏览器:
var myArr=[{id:'a'},{id:'myid'},{id:'c'}];
var索引=myArr.findIndex(函数(o){
返回o.id=='myid';
})
如果(索引!==-1)myArr.拼接(索引,1);
如果您喜欢简短的自描述性参数,或者如果您不想使用拼接
并使用直接筛选,或者如果您只是像我这样的SQL用户:
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' } ]
和示例用法:
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});
}
根据你的回答将是这样的。单击某个特定对象时,请在参数中为delete me函数发送索引。这个简单的代码会很有魅力
var arrayOfObjects = [{id:'abc',name:'oh'}, // delete me
{id:'efg',name:'em'}, // delete me
{id:'hij',name:'ge'}] // all that should remain
使用Set和ES6过滤器检查这一点
function deleteme(i){
if (i > -1) {
arrayOfObjects.splice(i, 1);
}
}
以下是JSFIDLE:
带有过滤器和索引
let result = arrayOfObjects.filter( el => (-1 == listToDelete.indexOf(el.id)) );
console.log(result);
带有筛选器和包含项
withLodash = _.filter(arrayOfObjects, (obj) => (listToDelete.indexOf(obj.id) === -1));
withoutLodash = arrayOfObjects.filter(obj => listToDelete.indexOf(obj.id) === -1);
根据给定数组中的对象id删除对象
withLodash = _.filter(arrayOfObjects, (obj) => (!listToDelete.includes(obj.id)))
withoutLodash = arrayOfObjects.filter(obj => !listToDelete.includes(obj.id));
您可以使用过滤器。如果条件为true,此方法始终返回元素。因此,如果要按id删除,则必须保留所有与给定id不匹配的元素。以下是一个示例:
arrayOfObjects=arrayOfObjects.filter(obj=>obj.id!=idToRemove)
var apps=[{id:34,名称:'My App',另一个:'thing'},{id:37,名称:'My New App',另一个:'things'}]
var removeIndex=apps.map(函数(项){return item.id;}).indexOf(37)
应用拼接(removeIndex,1) 向后循环应该可以解决长度变化的问题。遗憾的是,没有一种标准的正确方法从对象数组中删除项。难怪有这么多第三方脚本。这是一个基本的东西。可能重复我如何删除对象数组中的所有项,但我也需要回调。你说的回调也是什么意思,你可以使用上面的代码从数组中删除对象。不错。我将把它添加到我的ToolBeltan中。另外,对于数组中的每个对象,都会有单独的按钮。如果要删除数组中的特定对象,请单击按钮,并将其移动到另一个辅助数组。怎么做。我使用angular js ng repeat生成项目。你能帮助我消除这个ES5建议吗?因为它甚至可以用更短的方式编写items.splice(items.findIndex(i=>i.id==“abc”),1)
注意,这个答案需要下划线库,我不建议这样做,因为如果找不到元素,index.xof将返回-1=>items.splice(-1,1)这是一个非常优雅的答案。我想要的另一件事是,数组中的每个对象都有单独的按钮。如果要删除数组中的特定对象,请单击按钮,并将其移动到另一个辅助数组。怎么做。我使用angular js ng repeat生成项目。你能帮我找到一个非常优雅的方法吗。荣誉只有一件事需要谨慎;若在映射数组中找不到所需索引,则返回-1;因此,splice将删除最后一个元素。或者,如果您对最后一行上的tilde感到困惑,您可能会发现这一点更清楚:(removeIndex>=0)和&array.splice(removeIndex,1)@议会-您的示例中是否有关于瓷砖的文档?我以前从未见过这种情况。我喜欢这个现代的答案,只是你的代码没有捕捉到index=-1v的情况
let result = arrayOfObjects.filter( el => (-1 == listToDelete.indexOf(el.id)) );
console.log(result);
withLodash = _.filter(arrayOfObjects, (obj) => (listToDelete.indexOf(obj.id) === -1));
withoutLodash = arrayOfObjects.filter(obj => listToDelete.indexOf(obj.id) === -1);
withLodash = _.filter(arrayOfObjects, (obj) => (!listToDelete.includes(obj.id)))
withoutLodash = arrayOfObjects.filter(obj => !listToDelete.includes(obj.id));
const hero = [{'id' : 1, 'name' : 'hero1'}, {'id': 2, 'name' : 'hero2'}];
//remove hero1
const updatedHero = hero.filter(item => item.id !== 1);