javascript-在for循环中使用拼接从数组中删除项目

我想实现一种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);
});
});

现在我的问题是,并非所有项目都在我的for循环中被删除。例如,如果我删除打字“这是一个测试”“是”,则“ a”保持不变。JSFIDDLE

我认为问题是for循环,因为如果我删除带有拼接的项,则数组的索引会发生变化,因此它会继续使用“错误的”索引。

也许有人可以帮助我吗?

SirDerpington asked 2020-01-24T01:27:08Z
4个解决方案
134 votes

解决方案1

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

var searchInput, i;

searchInput = ["this", "is", "a", "test"];
i = searchInput.length;
while (i--) {
    if (searchInput[i].length < 4) {
        searchInput.splice(i, 1);
    }
}

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

这是因为在数组上进行增量迭代,在进行拼接时,数组会被修改到位,因此项目被“移位”,最终跳过了某些迭代。 向后循环(使用Array.prototype.filter甚至filter循环)可以解决此问题,因为您没有按照拼接的方向循环。


解决方案2

同时,生成新数组而不是就地修改数组通常更快。 这是一个例子:

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

其中Array.prototype.filter仅包含有效长度的项目,而您仍然具有filter中的原始项目。

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


解决方案3

除了上面的第二个解决方案,还有一个类似的更新的Array.prototype.filter方法可以更好地处理该问题:filter。这是一个示例:

var searchInput, newSearchInput;

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

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


参考文献:

  • Array.prototype.filter-[https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/filter]
  • Array.prototype.filter浏览器支持-[http://kangax.github.io/es5-compat-table/#Array.prototype.filter]
Ian answered 2020-01-24T01:28:25Z
5 votes
var myArr = [0,1,2,3,4,5,6];

问题陈述:

myArr.splice(2,1);

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

现在3个动作在第二个位置移动,长度减少了1个,这就造成了问题。

解决方案:一个简单的解决方案是在拼接时以相反的方向进行迭代。

var i = myArr.length;
while (i--) {
    // do your stuff
}
Arun Pratap Singh answered 2020-01-24T01:28:54Z
2 votes

如果您安装了lodash库,则可能要考虑它们。

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

这是一个例子。

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

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

    if (value.length < 4) {
        searchInput.splice(key, 1);
    }
});
Clinton Dobbs answered 2020-01-24T01:29:23Z
1 votes

您还可以使用$ .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/]

dfsq answered 2020-01-24T01:29:47Z
translate from https://stackoverflow.com:/questions/16217333/remove-items-from-array-with-splice-in-for-loop