Как я могу удалить элемент из списка с помощью 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?

Саманта JT Star
источник
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});
thefourtheye
источник
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});

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

semirturgay
источник
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;
});
Xeltor
источник
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

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

mqliutie
источник
Я искалreject
Сампгун
2

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

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

ИЛИ

obj.subTopics = _.filter(obj.subTopics, (currentObject) => {
    return currentObject.subTopicId !== stToDelete;
});
Пранав Сингх
источник
1

Лодаш и машинопись

const clearSubTopics = _.filter(obj.subTopics, topic => (!_.isEqual(topic.subTopicId, 2)));
console.log(clearSubTopics);
Ульяна Павелко
источник
0

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

index_tobe_delete = 1

fruit = [{a: "apple"}, {b: "banana"}, {c: "choco"}]
_.filter(fruit, (value, key)=> {
return (key !== index_tobe_delete)
})
Анупам Маурья
источник