Видаліть елемент із масиву за допомогою UnderscoreJS


137

Скажіть, у мене є цей код

var arr = [{id: 1, name: 'a'}, {id: 2, name: 'b'}, {id: 3, name: 'c'}];

і я хочу видалити елемент з id = 3 з масиву. Чи існує спосіб зробити це без сплайсингу? Має щось, використовуючи підкреслення чи щось подібне?

Дякую!


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

6
Що не так у зрощенні?
Šime Vidas

Ви перевірили посилання підкреслення?
Šime Vidas

Просто за допомогою простого JavaScript це дублікат видалення об'єктів з масиву за властивістю об'єкта .
Фелікс Клінг

5
добре, це не дублікат, оскільки він має тег для underscore.js
Garis M Suero

Відповіді:


279

Лише використовуючи звичайний JavaScript, на це вже відповіли: видаліть об’єкти з масиву за властивістю об’єкта .

Використовуючи underscore.js, ви можете комбінувати .findWhereз .without:

var arr = [{
  id: 1,
  name: 'a'
}, {
  id: 2,
  name: 'b'
}, {
  id: 3,
  name: 'c'
}];

//substract third
arr = _.without(arr, _.findWhere(arr, {
  id: 3
}));
console.log(arr);
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>

Хоча, оскільки ви в будь-якому випадку створюєте новий масив, ви можете просто скористатись _.filterнативною Array.prototype.filterфункцією (як це показано в іншому запитанні). Тоді ви б лише повторили масив один раз, а не два рази, як тут.

Якщо ви хочете змінити масив на місці , вам доведеться скористатися .splice. Це також показано в іншому запитанні, і, мабуть, невизначеність не дає корисної функції для цього.


1
Так, це прекрасно працює, я переглянув документацію підкреслення, але не зовсім зрозумів, як це витягнути. Дякую!
альпініст

10
Чи не буде _.reject або _.filter () набагато ефективнішими? Ви закінчите дві ітерації списку, щоб витягнути один елемент.
Рік Штраль

1
Це може бути дублікат, але це краща відповідь.
Майкл Дж. Калкінс

2
@RickStrahl Ви праві. _.rejectТут виглядає кращий вибір.
Тарік

1
@lukaserat, щоб випустити останній елемент, використовуй arr.pop()...
Еміль Бержерон

96

Ви можете використовувати підкреслення .filter

    var arr = [{
      id: 1,
      name: 'a'
    }, {
      id: 2,
      name: 'b'
    }, {
      id: 3,
      name: 'c'
    }];

    var filtered = _(arr).filter(function(item) {
         return item.id !== 3
    });

Можна також записати як:

var filtered = arr.filter(function(item) {
    return item.id !== 3
});

var filtered = _.filter(arr, function(item) {
    return item.id !== 3
});

Перевірте Fiddle

Ви також можете використовувати .reject


Я думаю, ви мали на увазі: var filtered = _.filter (arr, function (item) {return item.id! == 3});
tbh__

2
@tbh__ _()створить обгортку навколо колекції, яка дозволить вам позначати методи підкреслення.
Сушант -

Я багато разів використовував підкреслення, я цього не знав. Дякую
tbh__


16

Підкреслення має метод _without (), який ідеально підходить для видалення елемента з масиву, особливо якщо у вас є об'єкт для видалення.

Повертає копію масиву зі всіма видаленими екземплярами значень.

_.without(["bob", "sam", "fred"], "sam");

=> ["bob", "fred"]

Працює і з більш складними об'єктами.

var bob = { Name: "Bob", Age: 35 };
var sam = { Name: "Sam", Age: 19 };
var fred = { Name: "Fred", Age: 50 };

var people = [bob, sam, fred]

_.without(people, sam);

=> [{ Name: "Bob", Age: 35 }, { Name: "Fred", Age: 50 }];

Якщо ви не маєте деталь , щоб видалити, тільки властивість цього, ви можете використовувати , _.findWhereа потім _.without.


2
Примітка: це працює лише тому, що ви передаєте сам об’єкт без. Якщо ви замість цього переходите { Name: "Sam", Age: 19 }до без, ніж змінна Sam, це більше не працює. Фіддл
Адам

5

Будьте уважні, якщо ви фільтруєте струни та шукаєте нечутливі до регістру фільтри. _.without () відрізняється від регістру. Ви також можете використовувати _.reject (), як показано нижче.

var arr = ["test","test1","test2"];

var filtered = _.filter(arr, function(arrItem) {
    return arrItem.toLowerCase() !== "TEST".toLowerCase();
});
console.log(filtered);
// ["test1", "test2"]

var filtered1 = _.without(arr,"TEST");
console.log(filtered1);
// ["test", "test1", "test2"]

var filtered2 = _.reject(arr, function(arrItem){ 
    return arrItem.toLowerCase() === "TEST".toLowerCase();
});
console.log(filtered2);
// ["test1", "test2"]

4

Інші відповіді створюють нову копію масиву, якщо ви хочете змінити масив на своєму місці, ви можете використовувати:

arr.splice(_.findIndex(arr, { id: 3 }), 1);

Але це передбачає, що елемент завжди знайдеться всередині масиву (адже якщо його не знайти, він все одно видалить останній елемент). Для безпеки ви можете використовувати:

var index = _.findIndex(arr, { id: 3 });
if (index > -1) {
    arr.splice(index, 1);
}

2

або іншим зручним способом:

_.omit(arr, _.findWhere(arr, {id: 3}));

мої 2 копійки


1
пропуск працює objectі повертає object. отже, не підходить для роботи з тим, Arraysде ми могли б очікувати arrayповернення після видалення елемента.
ScrapCode

1
Отже, _. без того, на що ви дивитесь: _.without([1, 2, 1, 0, 3, 1, 4], 0, 1); => [2, 3, 4]
Надей

2

Використовуйте звичайнийArray#filter метод JavaScript на зразок цього:

var arr = [{id:1,name:'a'},{id:2,name:'b'},{id:3,name:'c'}];

var filteredArr = arr.filter(obj => obj.id != 3);

console.log(filteredArr);

Або використовувати Array#reduceі такі Array#concatметоди , як це:

var arr = [{id:1,name:'a'},{id:2,name:'b'},{id:3,name:'c'}];

var reducedArr = arr.reduce((accumulator, currObj) => {
  return (currObj.id != 3) ? accumulator.concat(currObj) : accumulator;
}, []);

console.log(reducedArr);

ПРИМІТКА:

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

0

Я раніше спробував цей метод

_.filter(data, function(d) { return d.name != 'a' });

Можуть бути і кращі методи, подібні до вищезазначених рішень, що надаються користувачами


0

Використовуючи underscore.js

var arr = [{id:1,name:'a'},{id:2,name:'b'},{id:3,name:'c'}];

var resultArr = _.reject(arr,{id:3});

console.log(resultArr);

Результат буде: [{id:1name:'a'},{id:2,name:'c'}]


-1

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

arr = _.reject(arr, function(objArr){ return objArr.id == 3; });
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.