JavaScript filter()结果在回调中总是为空?

时间:2017-03-09 12:22:59

标签: javascript arrays filter

任务:仅保留数组中的唯一值。测试用例:

<script>
var ar1 = [1,1];
var ar2 = [];
ar2 = ar1.filter( function( x ) {
    return ( ar2.indexOf(x) < 0 ); // <== always returns true
})
console.log( ar2 ); // <== "Array [ 1, 1 ]" FAIL!
</script>

问题:看起来在filter()回调内部得到的数组没有得到更新。它是否正确?为什么? (我几乎确信我的代码中有一个我无法看到的拼写错误,因为直觉上它应该工作。所以我必须误解filter()一英里。)

3 个答案:

答案 0 :(得分:2)

问题出在您的代码中ar2.indexOf(x) < 0

基本上它始终返回true,因为ar2自初始化以来不包含1(同样指出@DanielB)。

您可以使用以下代码,这些代码只保留数组中的唯一值。

ES6版本:

let ar1 = [1, 1, 2, 2, 2],
    ar2 = ar1.filter((item, pos) => ar1.indexOf(item) === pos);
console.log(ar2);

ES5版本:

var ar1 = [1, 1, 2, 2, 2],
    ar2 = ar1.filter(function(item, pos) {
        return ar1.indexOf(item) === pos;
    });
console.log(ar2);

答案 1 :(得分:2)

您的代码与此相同:

var ar1 = [1,1];
var ar2 = [];
var tmp = ar1.filter( function( x ) {
    return ( ar2.indexOf(x) < 0 ); // <== always returns true
})
ar2 = tmp;

我想告诉您ar2仅在ar1.filter完成后,即在迭代整个数组之后更新为新值。所以“总是回归真实”是预期的行为。

要解决您的任务,您必须这样做:

var ar1 = [1,1];
var ar2 = [];
for (let x of ar1) {
    if (ar2.indexOf(x) < 0) {
        ar2.push(x);
    }
}

所以在这里我们遍历数组并检查ar2中是否已经显示了这个项目,并立即推送项目,以便ar2始终在所有迭代中保持最新。< / p>

(警告:示例中使用了ES6语法)

答案 2 :(得分:-1)

我认为你的问题是删除数组中的重复项。使用tmp数组。因为在完成过滤之前ar2总是为空。所以回调总是返回true。

使用临时数组

&#13;
&#13;
var ar1 = [1,5,6,1];
var tmp=[];
var ar2 = ar1.filter( function( x ) {
    return tmp.indexOf(x)<0&&tmp.push(x);
})
console.log( ar2 ); 
&#13;
&#13;
&#13;

或者使用array reduce而不是

&#13;
&#13;
var ar1 = [1,5,6,1];
var ar2 = ar1.reduce(function(array,x) {
    if(array.indexOf(x)<0) array.push(x);
    return array;
},[])
console.log( ar2 ); 
&#13;
&#13;
&#13;