Tengo dos matrices. La primera matriz contiene algunos valores, mientras que la segunda matriz contiene índices de los valores que deben eliminarse de la primera matriz. Por ejemplo:
var valuesArr = new Array("v1","v2","v3","v4","v5");
var removeValFromIndex = new Array(0,2,4);
Quiero eliminar los valores presentes en los índices 0,2,4
de valuesArr
. Pensé que el splice
método nativo podría ayudar, así que se me ocurrió:
$.each(removeValFromIndex,function(index,value){
valuesArr.splice(value,1);
});
Pero no funcionó porque después de cada uno splice
, los índices de los valores valuesArr
eran diferentes. Podría resolver este problema usando una matriz temporal y copiando todos los valores en la segunda matriz, pero me preguntaba si existen métodos nativos a los que podamos pasar múltiples índices en los que eliminar valores de una matriz.
Preferiría una solución jQuery. (No estoy seguro si puedo usar grep
aquí)
fuente
$.each(rvm.reverse(), function(e, i ) {})
removeValFromIndex
está ordenado en orden ascendenteAquí hay uno que uso cuando no voy con lodash / subrayado:
fuente
slice
tendrías que volver a calcular los índices que se eliminarían (-1 enIndexestoBeRemoved
), ¡pero en realidad funciona!IndexesToBeRemoved
matriz se ordena en forma ascendente.IndexesToBeRemoved
está ordenado (ascendente).No,
in-place
pero se puede hacer usandogrep
yinArray
funciones dejQuery
.mira este violín.
fuente
valuesArr = $.grep(...);
Le sugiero que use Array.prototype.filter
fuente
La referencia de MDN está aquí
fuente
En JS puro, puede recorrer la matriz hacia atrás, por
splice()
lo que no estropeará los índices de los elementos siguientes en el ciclo:fuente
Se siente necesario publicar una respuesta con
O(n)
tiempo :). El problema con la solución de empalme es que debido a que la implementación subyacente de la matriz es literalmente una matriz , cadasplice
llamada llevaráO(n)
tiempo. Esto es más pronunciado cuando configuramos un ejemplo para explotar este comportamiento:Esto elimina elementos comenzando desde el medio hasta el inicio, por lo tanto, cada eliminación obliga al motor js a copiar
n/2
elementos, tenemos(n/2)^2
operaciones de copia en total que son cuadráticas.La solución de empalme (suponiendo
is
que ya esté ordenada en orden decreciente para deshacerse de los gastos generales) es la siguiente:Sin embargo, no es difícil implementar una solución de tiempo lineal, reconstruyendo la matriz desde cero, usando una máscara para ver si copiamos elementos o no (sort empujará esto a
O(n)log(n)
). La siguiente es una implementación de este tipo (nomask
es que sea booleano invertido para la velocidad):Ejecuté esto en jsperf.com e incluso
n=100
el método de empalme es un 90% más lento. Para mayorn
esta diferencia será mucho mayor.fuente
Quick ES6 one liner:
fuente
removeValFromIndex
unSet()
y usa enremoveValFromIndex.has
lugar deincludes
.Una solución simple y eficiente (complejidad lineal) que usa filter y Set :
La gran ventaja de esa implementación es que la operación (
has
función) de búsqueda Establecer toma un tiempo constante, siendo más rápida que la respuesta de nevace, por ejemplo.fuente
Esto funciona bien para mí y también funciona al eliminar de una matriz de objetos:
Puede haber una forma más corta y eficiente de escribir esto, pero funciona.
fuente
Una solución simple con ES5. Esto parece más apropiado para la mayoría de las aplicaciones hoy en día, ya que muchas ya no quieren depender de jQuery, etc.
Cuando los índices que se eliminarán se ordenan en orden ascendente:
Cuando los índices que se eliminarán no están ordenados:
fuente
Puede corregir su código reemplazando
removeValFromIndex
conremoveValFromIndex.reverse()
. Si no se garantiza que esa matriz use orden ascendente, puede usarremoveValFromIndex.sort(function(a, b) { return b - a })
.fuente
removeValFromIndex
están en orden ascendente.Aquí hay una posibilidad:
Ejemplo en jsFiddle
MDN en Array.prototype.reduceRight
fuente
Si está usando underscore.js , puede usarlo
_.filter()
para resolver su problema.Además, si está intentando eliminar elementos utilizando una lista de elementos en lugar de índices, simplemente puede usar
_.without()
, así:Ahora
filteredArr
debería ser["V2", "V4", "V5"]
fuente
filter + indexOf (IE9 +):
O con el filtro ES6 + buscar (Edge +):
fuente
Aquí tienes un rapidito.
fuente
Parece que Aplicar podría ser lo que estás buscando.
tal vez algo como esto funcionaría?
fuente
.splice()
método no espera una lista de elementos para eliminar, espera un índice único del elemento en el que comenzar a eliminar seguido del número de elementos a eliminar ...Para artículos múltiples o artículo único:
Le sugiero que use Array.prototype.filter
¡Nunca use indexOf si ya conoce el índice !:
Hacer:
con Hashes ... usando Array.prototype.map
fuente
Esto funciona. Sin embargo, haría una nueva matriz en el proceso. No estoy seguro de si eso es lo que desea o no, pero técnicamente sería una matriz que contiene solo los valores que desea.
fuente
Puede probar y usar.
delete array[index]
Esto no eliminará completamente el elemento, sino que establece el valor enundefined
.fuente
Puede construir un a
Set
partir de la matriz y luego crear una matriz a partir del conjunto.fuente