javascript - array - Eliminar elementos de la matriz con empalme en bucle
iterate array javascript foreach (4)
Solución 1
Puede realizar un ciclo hacia atrás, con algo como lo siguiente:
var searchInput, i;
searchInput = ["this", "is", "a", "test"];
i = searchInput.length;
while (i--) {
if (searchInput[i].length < 4) {
searchInput.splice(i, 1);
}
}
DEMO: http://jsfiddle.net/KXMeR/
Esto se debe a que se itera incrementalmente a través de la matriz, cuando la empalmas, la matriz se modifica en su lugar, por lo que los elementos se "desplazan" y terminas salteando la iteración de algunos. Hacer un bucle hacia atrás (con un while
o incluso un bucle for
) lo soluciona porque no estás haciendo un bucle en la dirección en la que estás empalmando.
Solución 2
Al mismo tiempo, generalmente es más rápido generar una nueva matriz en lugar de modificar una en su lugar. Aquí hay un ejemplo:
var searchInput, newSearchInput, i, j, cur;
searchInput = ["this", "is", "a", "test"];
newSearchInput = [];
for (i = 0, j = searchInput.length; i < j; i++) {
cur = searchInput[i];
if (cur.length > 3) {
newSearchInput.push(cur);
}
}
donde newSearchInput
solo contendrá elementos de longitud válidos, y aún tendrá los elementos originales en searchInput
.
DEMO: http://jsfiddle.net/RYAx2/
Solución 3
Además de la segunda solución anterior, hay disponible un método Array.prototype
similar y más nuevo para manejar mejor: filter
. Aquí hay un ejemplo:
var searchInput, newSearchInput;
searchInput = ["this", "is", "a", "test"];
newSearchInput = searchInput.filter(function (value, index, array) {
return (value.length > 3);
});
DEMO: http://jsfiddle.net/qky7D/
Referencias
-
Array.prototype.filter
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter - Soporte del navegador
Array.prototype.filter
- http://kangax.github.io/es5-compat-table/#Array.prototype.filter
Quiero implementar un tipo de búsqueda en vivo de jQuery. Pero antes de enviar la entrada al servidor me gustaría eliminar todos los elementos en mi matriz que tienen 3 o menos caracteres (porque en el idioma alemán, esas palabras generalmente se pueden ignorar en términos de búsqueda) Entonces ["this", "is", "a", "test"]
convierte en ["this", "test"]
$(document).ready(function() {
var timer, searchInput;
$(''#searchFAQ'').keyup(function() {
clearTimeout(timer);
timer = setTimeout(function() {
searchInput = $(''#searchFAQ'').val().match(//w+/g);
if(searchInput) {
for (var elem in searchInput) {
if (searchInput[elem].length < 4) {
//remove those entries
searchInput.splice(elem, 1);
}
}
$(''#output'').text(searchInput);
//ajax call here
}
}, 500);
});
});
Ahora mi problema es que no todos los elementos se eliminan en mi bucle for. Si, por ejemplo, "esto es una prueba", "se elimina", "se queda". JSFIDDLE
Creo que el problema es el bucle for porque los índices de la matriz cambian si elimino un elemento con empalme, por lo que continúa con el índice "incorrecto".
Quizás alguien podría ayudarme?
Si tienes la biblioteca lodash instalada, tienen una joya dulce que quizás quieras considerar.
La función es _.forEachRight (itera sobre elementos de una colección de derecha a izquierda)
Aquí hay un ejemplo.
var searchInput = ["this", "is", "a", "test"];
_.forEachRight(searchInput, function(value, key) {
if (value.length < 4) {
searchInput.splice(key, 1);
}
});
También puede usar la función $.grep para filtrar una matriz:
var timer, searchInput;
$(''#searchFAQ'').keyup(function () {
clearTimeout(timer);
timer = setTimeout(function () {
searchInput = $(''#searchFAQ'').val().split(//s+/g); // match is okay too
searchInput = $.grep(searchInput, function(el) {
return el.length >= 4;
});
console.log(searchInput);
}, 500);
});
var myArr = [0,1,2,3,4,5,6];
Planteamiento del problema:
myArr.splice(2,1);
// [0, 1, 3, 4, 5, 6];
ahora 3 movimientos en la segunda posición y la longitud se reduce en 1, lo que crea un problema.
Solución: una solución simple sería iterar en sentido inverso al empalmar.
var i = myArr.length;
while (i--) {
// do your stuff
}