У меня два массива. Первый массив содержит некоторые значения, а второй массив содержит индексы значений, которые должны быть удалены из первого массива. Например:
var valuesArr = new Array("v1","v2","v3","v4","v5");
var removeValFromIndex = new Array(0,2,4);
Я хочу удалить значения, присутствующие в индексах 0,2,4
из valuesArr
. Я подумал, что собственный splice
метод может помочь, поэтому я придумал:
$.each(removeValFromIndex,function(index,value){
valuesArr.splice(value,1);
});
Но это не сработало, потому что после каждого splice
индексы значений valuesArr
были разными. Я мог бы решить эту проблему, используя временный массив и скопировав все значения во второй массив, но мне было интересно, есть ли какие-нибудь собственные методы, которым мы можем передать несколько индексов, по которым можно удалить значения из массива.
Я бы предпочел решение jQuery. (Не уверен, что могу использовать grep
здесь)
источник
$.each(rvm.reverse(), function(e, i ) {})
removeValFromIndex
будет отсортировано в порядке возрастанияВот тот, который я использую, когда не использую lodash / подчеркивание:
источник
slice
вам придется пересчитывать индексы, которые нужно удалить (-1IndexestoBeRemoved
), но это действительно работает!IndexesToBeRemoved
массив отсортирован по возрастанию.IndexesToBeRemoved
отсортировано (по возрастанию).Нет,
in-place
но можно использоватьgrep
иinArray
функцииjQuery
.проверьте эту скрипку.
источник
valuesArr = $.grep(...);
Я предлагаю вам использовать Array.prototype.filter
источник
Ссылка MDN здесь
источник
В чистом JS вы можете перебирать массив в обратном направлении, чтобы
splice()
не испортить индексы элементов, следующих в цикле:источник
Считаю необходимым дать ответ со
O(n)
временем :). Проблема со сращиванием заключается в том, что из-за базовой реализации массива, который буквально является массивом , каждыйsplice
вызов будет заниматьO(n)
время. Это наиболее ярко проявляется, когда мы настраиваем пример использования этого поведения:Это удаляет элементы, начиная с середины до начала, поэтому каждое удаление заставляет движок js копировать
n/2
элементы, у нас есть(n/2)^2
операции копирования в целом, которые являются квадратичными.Решение для стыковки (при условии
is
оно уже отсортировано в порядке убывания, чтобы избавиться от накладных расходов) выглядит следующим образом:Однако нетрудно реализовать решение с линейным временем, воссоздав массив с нуля, используя маску, чтобы увидеть, копируем ли мы элементы или нет (сортировка подтолкнет это к
O(n)log(n)
). Ниже приводится такая реализация (не таmask
логическое значение инвертировано для скорости):Я запускал это на jsperf.com, и даже
n=100
метод сращивания работает на 90% медленнее. Для большегоn
эта разница будет намного больше.источник
Quick ES6 с одним вкладышем:
источник
removeValFromIndex
Set()
removeValFromIndex.has
includes
Простое и эффективное (линейной сложности) решение с использованием filter и Set :
Большим преимуществом этой реализации является то, что операция (
has
функция) поиска Set занимает постоянное время, например, быстрее, чем ответ Nevace.источник
Это хорошо работает для меня и работает при удалении из массива объектов:
Может быть более короткий и эффективный способ написать это, но он работает.
источник
Простое решение с использованием ES5. В настоящее время это кажется более подходящим для большинства приложений, поскольку многие больше не хотят полагаться на jQuery и т. Д.
Когда удаляемые индексы отсортированы в порядке возрастания:
Когда удаляемые индексы не отсортированы:
источник
Вы можете исправить свой код, заменив его
removeValFromIndex
наremoveValFromIndex.reverse()
. Если не гарантируется, что в этом массиве используется возрастающий порядок, вы можете вместо этого использоватьremoveValFromIndex.sort(function(a, b) { return b - a })
.источник
removeValFromIndex
в порядке возрастания.Вот одна возможность:
Пример на jsFiddle
MDN на Array.prototype.reduceRight
источник
Если вы используете underscore.js , вы можете использовать его
_.filter()
для решения своей проблемы.Кроме того, если вы пытаетесь удалить элементы, используя список элементов вместо индексов, вы можете просто использовать
_.without()
, например:Теперь
filteredArr
должно быть["V2", "V4", "V5"]
источник
фильтр + indexOf (IE9 +):
Или с фильтром ES6 + find (Edge +):
источник
Вот быстрый прием.
источник
Похоже, что Apply может быть тем, что вы ищете.
может что-то подобное сработает?
источник
.splice()
метод не ожидает списка удаляемых элементов, он ожидает единый индекс элемента, с которого нужно начать удаление, за которым следует количествоДля нескольких элементов или уникального элемента:
Я предлагаю вам использовать Array.prototype.filter
Никогда не используйте indexOf, если вы уже знаете индекс !:
Делать:
с хешами ... используя Array.prototype.map
источник
Это работает. Однако в процессе вы создадите новый массив. Не уверен, хотите вы этого или нет, но технически это будет массив, содержащий только нужные вам значения.
источник
Вы можете попробовать и использовать.
delete array[index]
Это не удалит элемент полностью, а скорее установит значениеundefined
.источник
Вы можете построить
Set
из массива, а затем создать массив из набора.источник