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

IT技术 javascript jquery arrays for-loop
2021-02-05 08:29:19

我想实现一种 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 循环,因为如果我删除一个带有 splice 的项目,数组的索引会发生变化,所以它会继续使用“错误”的索引。

也许有人可以帮助我?

5个回答

方案一

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

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/

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


解决方案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);
    }
}

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

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


解决方案3

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

var searchInput, newSearchInput;

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

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


参考:

@SirDerpington 哈哈没问题,谢谢:) 是的,这完全取决于您的实施。我更喜欢第一个示例,除非您需要引用原始数组,即使splice速度稍慢(除非此代码在大型数组上快速运行数次,否则您不会看到速度差异)。
2021-03-18 08:29:19
looping in the direction you're splicing 惊人的概念。
2021-03-20 08:29:19
我会说你拯救了我的一天,但我已经浪费了一天的时间来弄清楚为什么我的代码不起作用 :D
2021-03-27 08:29:19
谢谢这做到了。有时你只是完全智障,你的大脑阻止了所有聪明的思考方式:D我会尽快接受这个答案;)
2021-04-02 08:29:19
正确解释的确切解决方案。非常感谢。
2021-04-05 08:29:19
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
}

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

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

这是一个例子。

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

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

    if (value.length < 4) {
        searchInput.splice(key, 1);
    }
});
非常好..真的很有帮助..谢谢
2021-03-21 08:29:19

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

另一种方法是在从数组 (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);

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