Як я можу видалити елемент із списку за допомогою 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) Це видалить усі відповідні значення зі списку.
boatcoder

Відповіді:


248

Як в коментарях вказували Лійони, більш ідіоматичним і лодашним способом зробити це було б використовувати _.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, якщо ви не хочете мутувати вихідний масив ....
random_user_name

@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 () - найкращий підхід, якщо ви хочете, щоб ваш масив було вимкнено. Якщо ви використовуєте delete, то він повертає новий масив, і його потрібно перепризначити.
omarjebari

Якщо ви хочете вилучити елемент з масиву за його індексом у масиві (очевидно, у вас є цей індекс, якщо ви хочете виконати дію видалення таким чином), то використання методу сплайсингу є найбільш ефективним (і простим) способом зробити це. Не потрібно нічого порівнювати та робити код складнішим та вразливішим для помилок та помилок ...
TheCuBeMan

26

ви можете це зробити з _pull.

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

перевірити посилання


7
За документами _.pullвикористовується сувора рівність для порівнянь, тобто === . Два різних простих об'єкта ніколи не будуть порівнюватись рівними ===(або ==для цього питання). Таким чином, ваш код вище ніколи не буде видаляти жоден елемент з масиву.
Марк Амері

1
Тим не менш, це єдиний, який працює з рядками в масиві. _.removeпросто промиває масив.
Яухені Пракопчик

3
Я все ще думаю, що це правильна відповідь. JS .filter видаляє всі збігаються елементи, JS .splice вимагає, щоб я знав індекс, _.remeve перебирає всі елементи масиву, таким чином, є менш ефективним. _.pull - це саме те, що я хочу: _.pull (масив, 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.