Как я могу удалить элемент из списка с помощью lodash?


166

У меня есть объект, который выглядит так:

var obj = {
    "objectiveDetailId": 285,
    "objectiveId": 29,
    "number": 1,
    "text": "x",
    "subTopics": [{
        "subTopicId": 1,
        "number": 1
    }, {
        "subTopicId": 2,
        "number": 32
    }, {
        "subTopicId": 3,
        "number": 22
    }]
}
var stToDelete = 2;

Я lodashустановил в своем приложении для других вещей. Есть ли эффективный способ использовать lodashдля удаления записи: {"subTopicId":2, "number":32}из objобъекта?

Или есть способ сделать это с помощью javascript?


1
Вы можете просто использовать splice( developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… ), чтобы удалить элемент из списка
z33m

1
Изменен заголовок, потому что удаление 4 из массива [1,4,5] не может быть сделано таким образом. Да, я понимаю, что массивы могут быть реализованы из хеша / объекта и, вероятно, есть, но в этих двух аспектах есть небольшая разница. Для удаления из массива вы должны использовать result = _.pull(arr, value) Это удалит все совпадающие значения из списка.
кодек

Ответы:


248

Как отмечалось в комментариях lyyons, более идиоматичным и хитрым способом сделать это было бы использовать _.remove, как это

_.remove(obj.subTopics, {
    subTopicId: stToDelete
});

Кроме того, вы можете передать функцию предиката, результат которой будет использоваться для определения необходимости удаления текущего элемента.

_.remove(obj.subTopics, function(currentObject) {
    return currentObject.subTopicId === stToDelete;
});

В качестве альтернативы, вы можете создать новый массив, отфильтровав старый _.filterи присвоив его тому же объекту, например так

obj.subTopics = _.filter(obj.subTopics, function(currentObject) {
    return currentObject.subTopicId !== stToDelete;
});

Или

obj.subTopics = _.filter(obj.subTopics, {subTopicId: stToKeep});

3
Причина этого ответа заключается в том, что вы можете использовать функцию предиката , которая именно то, что я искал. Удаление элемента является тривиальным, если вы знаете индекс, но что делать, если вы не знаете индекс?
random_user_name

3
Возможно, стоит упомянуть _.filter, если вы не хотите
изменять

@cale_b Спасибо :-) Обновил ответ с _.filterверсией.
thefourtheye

7
@thefourtheye _.filter возвращает элемент, если предикат верен. Ваша реализация вернет все нежелательные элементы вместо тех, которые вы хотите сохранить
Xeltor

5
@thefourtheye, вы должны использовать _.rejectвместо того _.filterже предиката. Проверьте мой ответ для более подробной информации!
Xeltor

29

Просто используйте ванильный JS. Вы можете использовать spliceдля удаления элемента:

obj.subTopics.splice(1, 1);

демонстрация


3
пользователь спрашиваетIs there an efficient way to use _lodash to delete
semirturgay

7
@ Andy Вы правы, но что, если индекс еще не известен?
thefourtheye

3
splice () - лучший подход, если вы хотите, чтобы ваш массив был видоизменён. Если вы используете команду remove, то она возвращает новый массив, и его необходимо переназначить.
Омаржебари

Если вы хотите удалить элемент из массива по его индексу в массиве (очевидно, у вас есть этот индекс, если вы хотите выполнить действие удаления таким способом), тогда использование метода сращивания является наиболее эффективным (и простым) способом. сделать это. Не нужно ничего сравнивать и делать код более сложным и уязвимым для ошибок и ошибок ...
TheCuBeMan

26

Вы можете сделать это с _pull.

_.pull(obj["subTopics"] , {"subTopicId":2, "number":32});

проверьте ссылку


7
Согласно документам, для сравнения_.pull используется строгое равенство, то есть === . Два разных простых объекта никогда не будут сравниваться как равные ===(или по ==этому вопросу). Таким образом, ваш код выше никогда не удалит какие-либо элементы из массива.
Марк Эмери

1
Тем не менее, это единственный, который работает со строками в массиве. _.removeпросто сбрасывает массив.
Yauheni Prakopchyk

3
Я все еще думаю, что это правильный ответ. JS .filter удаляет все совпадающие элементы, JS .splice требует, чтобы я знал индекс, _.remove выполняет итерации по всем элементам массива, таким образом, будучи менее эффективным. _.pull это именно то, что я хочу: _.pull (array, itemToRemove).
Иуда Габриэль Химанго

21

Теперь вы можете использовать _.reject, который позволяет вам фильтровать на основе того, от чего вам нужно избавиться, а не того, что вам нужно сохранить.

в отличие от _.pullили , _.removeчто только работа над массивами, ._rejectработает на любой Collection

obj.subTopics = _.reject(obj.subTopics, (o) => {
  return o.number >= 32;
});

2

Есть четыре способа сделать это, как я знаю

const array = [{id:1,name:'Jim'},{id:2,name:'Parker'}];
const toDelete = 1;

Первый:

_.reject(array, {id:toDelete})

Второй:

_.remove(array, {id:toDelete})

Таким образом, массив будет видоизменяться.

Третий:

_.differenceBy(array,[{id:toDelete}],'id')
// If you can get remove item 
// _.differenceWith(array,[removeItem])

Последний из них:

_.filter(array,({id})=>id!==toDelete)

Я изучаю lodash

Ответьте, чтобы сделать запись, чтобы я мог найти ее позже.


Я искалreject
Сампгун

2

В дополнение к ответу @thefourtheye, используя предикат вместо традиционных анонимных функций:

  _.remove(obj.subTopics, (currentObject) => {
        return currentObject.subTopicId === stToDelete;
    });

ИЛИ

obj.subTopics = _.filter(obj.subTopics, (currentObject) => {
    return currentObject.subTopicId !== stToDelete;
});


0

Вот простая функция lodash с массивом и удаление ее с индексным номером.

index_tobe_delete = 1

fruit = [{a: "apple"}, {b: "banana"}, {c: "choco"}]
_.filter(fruit, (value, key)=> {
return (key !== index_tobe_delete)
})
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.