Javascript 按对象属性从数组中删除对象

Javascript 按对象属性从数组中删除对象,javascript,Javascript,如何通过匹配对象属性从数组中删除对象 请只使用本机JavaScript 我在使用剪接时遇到问题,因为每次删除时长度都会减少。 在原始索引上使用克隆和剪接仍然会给您带来长度递减的问题。我想您使用了splice类似的东西 var listToDelete = ['abc', 'efg']; var arrayOfObjects = [{id:'abc',name:'oh'}, // delete me {id:'efg',name:'em'}, // d

如何通过匹配对象属性从数组中删除对象

请只使用本机JavaScript

我在使用剪接时遇到问题,因为每次删除时长度都会减少。
在原始索引上使用克隆和剪接仍然会给您带来长度递减的问题。

我想您使用了
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);