web-dev-qa-db-fra.com

Supprimer des éléments du tableau avec une épissure dans la boucle

Je veux implémenter une sorte de recherche en direct jQuery. Mais avant d'envoyer l'entrée au serveur, je voudrais supprimer tous les éléments de mon tableau qui ont 3 caractères ou moins (car en allemand, ces mots peuvent généralement être ignorés en termes de recherche). Donc ["this", "is", "a", "test"] devient ["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);
});
});

Maintenant, mon problème est que tous les éléments ne sont pas supprimés dans ma boucle for. Par exemple, si je tape "ceci est un test" "est" est supprimé, "a" reste. JSFIDDLE

Je pense que le problème est la boucle for car les index du tableau changent si je supprime un élément avec une épissure, donc ça continue avec le "mauvais" index.

Peut-être que quelqu'un pourrait m'aider?

48
SirDerpington

Solution 1

Vous pouvez boucler en arrière, avec quelque chose comme ceci:

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/

C'est parce que l'itération incrémentielle à travers le tableau, lorsque vous l'épissez, le tableau est modifié en place, donc les éléments sont "décalés" et vous finissez par ignorer l'itération de certains. La boucle vers l'arrière (avec une boucle while ou même for) corrige cela parce que vous ne bouclez pas dans la direction où vous épissez.


Solution 2

Dans le même temps, il est généralement plus rapide de générer un nouveau tableau au lieu d'en modifier un en place. Voici un exemple:

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);
    }
}

newSearchInput ne contiendra que des éléments de longueur valide, et vous avez toujours les éléments d'origine dans searchInput.

DEMO: http://jsfiddle.net/RYAx2/


Solution 3

En plus de la deuxième solution ci-dessus, une _ Array.prototype est disponible pour mieux gérer cela: filter. Voici un exemple:

var searchInput, newSearchInput;

searchInput = ["this", "is", "a", "test"];
newSearchInput = searchInput.filter(function (value, index, array) {
    return (value.length > 3);
});

DEMO: http://jsfiddle.net/qky7D/


Références:

131
Ian
var myArr = [0,1,2,3,4,5,6];

Énoncé du problème:

myArr.splice(2,1);

  \\ [0, 1, 3, 4, 5, 6];

maintenant 3 mouvements à la deuxième position et la longueur est réduite de 1, ce qui crée un problème.

Solution: Une solution simple serait d'itérer en sens inverse lors de l'épissage.

var i = myArr.length;
while (i--) {
    // do your stuff
}
5
Arun Pratap Singh

Si vous avez installé la bibliothèque lodash, ils ont un petit bijou que vous voudrez peut-être envisager.

La fonction est _. ForEachRight (itère les éléments d'une collection de droite à gauche)

Voici un exemple.

var searchInput = ["this", "is", "a", "test"];

_.forEachRight(searchInput, function(value, key) {

    if (value.length < 4) {
        searchInput.splice(key, 1);
    }
});
2
Clinton Dobbs

Vous pouvez également utiliser la fonction $. Grep pour filtrer un tableau:

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);
});

http://jsfiddle.net/dfsq/4Wdp9/

1
dfsq