удалять объекты из массива по свойству объекта

var listToDelete = [ 'abc' , 'efg' ];  

var arrayOfObjects = [{ id : 'abc' , name : 'oh' }, // delete me { id : 'efg' , name : 'em' }, // delete me { id : 'hij' , name : ' ge ' }] // все, что должно остаться nt prettyprinted ">  
                       
                       splice

Как удалить объект из массива путем сопоставления свойства объекта?

Только родной JavaScript, пожалуйста.

У меня возникают проблемы , используя для ( вар я = 0 ; я < arrayOfObjects . Длина ; я ++) { вар OBJ = arrayOfObjects [ я ]; if ( listToDelete . indexOf ( obj . id ) ! == - 1 ) { arrayOfObjects . сращивание ( i , 1 ); } }, поскольку длина уменьшается с каждым удалением. Использование клонирования и сплайсинга по индексу orignal все еще оставляет вам проблему уменьшения длины.

javascript,

96

Ответов: 11


122 принят

Я полагаю, вы использовали spliceчто-то вроде этого?

i

Все, что вам нужно сделать, чтобы исправить ошибку, уменьшается iв следующий раз, тогда (и цикл назад также является опцией):

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;

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 = 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;

которые могут быть завернуты в приятную функцию:

const filterInPlace = (array, predicate) => {
    let end = 0;

    for (let i = 0; i < array.length; i++) {
        const obj = array[i];

        if (predicate(obj)) {
            array[end++] = obj;
        }
    }

    array.length = end;
};

const toDelete = new Set(['abc', 'efg']);

const arrayOfObjects = [{id: 'abc', name: 'oh'},
                        {id: 'efg', name: 'em'},
                        {id: 'hij', name: 'ge'}];

filterInPlace(arrayOfObjects, obj => !toDelete.has(obj.id));
console.log(arrayOfObjects);

Если вам не нужно делать это на месте, вот что Array#filter:

const toDelete = new Set(['abc', 'efg']);
const newArray = arrayOfObjects.filter(obj => !toDelete.has(obj.id));

54

Вы можете удалить элемент по одному из своих свойств без использования каких-либо сторонних библиотек, таких как:

var removeIndex = array.map(function(item) { return item.id; })
                       .indexOf("abc");

~removeIndex && array.splice(removeIndex, 1);

20

var myArr = [{ id : 'a' }, { id : 'myid' }, { id : 'c' }]; var index = arr . findIndex ( function ( o ) { return o . id === 'myid' ; }) if ( index ! == - 1 ) myArr . сплайсинг ( индекс , 1 ); работает для современных браузеров:

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);

11 ов

С помощью lodash / подчеркивания:

Если вы хотите изменить существующий массив, тогда нам нужно использовать сплайсинг . Вот немного лучше / удобочитаемый способ, используя findWhere of underscore / lodash:

findIndex

С ES5 или выше

( без lodash / подчеркивания )

С ES5 вперед у нас есть findIndexметод на массиве, поэтому его легко без lodash / подчеркивания

items.splice(items.findIndex(function(i){
    return i.id === "abc";
}), 1);

(ES5 поддерживается практически во всех браузерах morden)

О пользователе findIndex


9

Если вы просто хотите удалить его из существующего массива и не создать новый, попробуйте:

var items = [{Id: 1},{Id: 2},{Id: 3}];
items.splice(_.indexOf(items, _.find(items, function (item) { return item.Id === 2; })), 1);
JavaScript,
Похожие вопросы