jQuery 使用 for 循环中的拼接从数组中删除项目

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16217333/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 16:42:55  来源:igfitidea点击:

Remove items from array with splice in for loop

javascriptjqueryarraysfor-loop

提问by SirDerpington

I want to implement a kind of jQuery live search. But before sending the input to the server I'd like to remove all items in my array which have 3 or less characters (because in the german language, those words usually can be ignored in terms of searching) So ["this", "is", "a", "test"]becomes ["this", "test"]

我想实现一种 jQuery 实时搜索。但是在将输入发送到服务器之前,我想删除数组中包含 3 个或更少字符的所有项目(因为在德语中,这些词通常可以在搜索方面被忽略)所以["this", "is", "a", "test"]变成["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);
});
});

Now my problem is that not all items get removed in my for loop. If I for example typ "this is a test" "is" gets removed, "a" stays. JSFIDDLE

现在我的问题是并非所有项目都在我的 for 循环中被删除。例如,如果我输入“这是一个测试”“是”被删除,“a”将保留。 JSFIDDLE

I think the problem is the for loop because the indexes of the array change if I remove an item with splice, so it goes on with the "wrong" index.

我认为问题是 for 循环,因为如果我删除一个带有 splice 的项目,数组的索引会发生变化,所以它会继续使用“错误”的索引。

Perhaps anybody could help me out?

也许有人可以帮助我?

回答by Ian

Solution 1

解决方案1

You can loop backwards, with something like the following:

您可以向后循环,如下所示:

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/

演示:http : //jsfiddle.net/KXMeR/

This is because iterating incrementally through the array, when you splice it, the array is modified in place, so the items are "shifted" and you end up skipping the iteration of some. Looping backwards (with a whileor even a forloop) fixes this because you're not looping in the direction you're splicing.

这是因为通过数组递增迭代,当你拼接它时,数组被修改到位,所以项目被“移动”,你最终会跳过一些迭代。向后循环(使用一个while或什至一个for循环)可以解决这个问题,因为您没有在拼接的方向上循环。



Solution 2

解决方案2

At the same time, it's usually faster to generate a new array instead of modifying one in place. Here's an example:

同时,生成新数组通常比原地修改更快。下面是一个例子:

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

where newSearchInputwill only contain valid length items, and you still have the original items in searchInput.

wherenewSearchInput将只包含有效长度的项目,并且您仍然在searchInput.

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

演示:http : //jsfiddle.net/RYAx2/



Solution 3

解决方案3

In addition to the second solution above, a similar, newer Array.prototypemethod is available to handle that better: filter. Here's an example:

除了上述,第二溶液的类似,更新Array.prototype方法可用于处理,更好地:filter。下面是一个例子:

var searchInput, newSearchInput;

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

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

演示:http : //jsfiddle.net/qky7D/



References:

参考:

回答by Arun Pratap Singh

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

Problem statement:

问题陈述:

myArr.splice(2,1);

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

now 3 moves at second position and length is reduced by 1 which creates problem.

现在 3 在第二个位置移动,长度减少 1,这会产生问题。

Solution:A simple solution would be iterating in reverse direction when splicing.

解决方案:一个简单的解决方案是拼接时反向迭代。

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

回答by Clinton Dobbs

If you have the lodashlibrary installed, they have a sweet gem you might want to consider.

如果您安装了lodash库,那么您可能会考虑使用它们。

The function is _.forEachRight(iterates over elements of a collection from right to left)

函数是_.forEachRight(从右到左迭代集合的元素)

Here is an example.

这是一个例子。

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

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

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

回答by dfsq

You can also use $.grepfunction to filter an array:

您还可以使用$.grep函数来过滤数组:

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/

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

回答by Muhammad Ali

Another approach would be to decrement the index whenever you slice from the array (x--), so that when the array gets shifted down the next element doesn't get skipped.

另一种方法是在从数组 (x--) 切片时递减索引,这样当数组向下移动时,下一个元素不会被跳过。

var searchInput;

searchInput = ["this", "is", "a", "test"];
for (var x = 0; x < searchInput.length; x++) {
    if (searchInput[x].length < 4) {
        searchInput.splice(x--, 1);
    }
}

console.log(searchInput);

DEMO:https://jsfiddle.net/alinaeem229/n2kq3690/1/

演示:https : //jsfiddle.net/alinaeem229/n2kq3690/1/