Удалить элемент из массива с помощью UnderscoreJS

139

Скажем, у меня есть этот код

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

и я хочу удалить элемент с id = 3 из массива. Есть ли способ сделать это без склейки? Может, что-то с подчеркиванием или что-то в этом роде?

Благодарность!

альпинистский
источник
Если вы не хотите создавать новый массив, единственный выбор - склейка. Держу пари, что подчеркивание тоже использует его (внутренне, если такой метод существует).
Felix Kling
6
Что не так со сращиванием?
Шиме Видас
Вы проверили ссылку на подчеркивание?
Шиме Видас
Просто используя простой JavaScript, это дубликат удаления объектов из массива по свойству объекта .
Felix Kling
5
ну не дублируется, так как у него есть тег для underscore.js
Гарис М. Суеро

Ответы:

280

Просто используя простой 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. Это также показано в другом вопросе, и undescore, похоже, не предоставляет для этого никакой полезной функции.

Феликс Клинг
источник
1
Да, это работает отлично, я просмотрел документацию с подчеркиванием, но не совсем понял, как вытащить ее без нее. Спасибо!
climboid 07
10
Разве _.reject или _.filter () не были бы здесь намного эффективнее? У вас будет две итерации списка, чтобы вытащить один элемент.
Rick Strahl
1
Это может быть дубликат, но это лучший ответ.
Майкл Дж. Калкинс
2
@RickStrahl Вы правы. _.rejectпохоже, здесь лучший выбор.
Tarik
1
@lukaserat, чтобы вытолкнуть последний элемент, используйте arr.pop()...
Эмиль Бержерон
96

Вы можете использовать Underscore .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
});

Проверить скрипку

Вы также можете использовать .reject

Сушант -
источник
Я думаю, вы имели в виду: var filter = _.filter (arr, function (item) {return item.id! == 3});
tbh__
2
@tbh__ _()создаст оболочку вокруг коллекции, которая позволит вам вызывать методы подчеркивания.
Sushanth -
Я много лет использую подчеркивание, я никогда этого не знал. Спасибо
tbh__
39

Используйте подчеркивание _.reject():

arr = _.reject(arr, function(d){ return d.id === 3; });
зеленыйафриканец
источник
с es6 вы можете сделатьarr = _.reject(arr, d => d.id === 3 );
greenafrican
16

В Underscore есть метод _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.

PeteGO
источник
2
Примечание: это работает только потому, что вы передаете объект sam без него. Если вы вместо этого перейдете { Name: "Sam", Age: 19 }к без переменной, а не к переменной sam, она больше не будет работать. Fiddle
Адам
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"]
Шрихари Шридхаран
источник
5

Другие ответы создают новую копию массива, если вы хотите изменить массив на месте, вы можете использовать:

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 08
1
Итак, _.without - это то, на что вы смотрите: _.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);

НОТА:

  • Оба они представляют собой чисто функциональный подход ( т.е. они не изменяют существующий массив).
  • Нет, для этого подхода требуется внешняя библиотека (достаточно Vanilla 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

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

arr = _.reject(arr, function(objArr){ return objArr.id == 3; });
СТАЛИ
источник