使用Number函数作为过滤器时Array.filter意外结果

时间:2019-04-24 10:33:37

标签: javascript arrays

我只是在使用Array.prototype.filter()时发现了这个问题,有人可以向我解释为什么?

我有这两个数组

[0, NaN, NaN, NaN]

[1, NaN, NaN, NaN]

当我使用Number类型的filter调用filter()时,第一个返回的是一个空数组,而第二个返回的是一个数组。

我认为将0的检查作为Number失败了,但是为什么呢?我试图用Number构造一个0,并且显然可以正常工作。

console.log([0, NaN, NaN, NaN].filter(Number)); // []

console.log([1, NaN, NaN, NaN].filter(Number)); // [1]

// other examples
console.log([0, 1, 2, 3].filter(Number)); // [1, 2, 3]

console.log([1, 2, 3, 4].filter(Number)); // [1, 2, 3, 4]

console.log([0.1, 0.2, 0.3, 0.4].filter(Number)); // [0.1, 0.2, 0.3, 0.4]

console.log([1.1, 2.2, 3.3, 4.4].filter(Number)); // [1.1, 2.2, 3.3, 4.4]

console.log([-1, -2, -3, -4].filter(Number)); // [-1, -2, -3, -4]

预先感谢男孩和女孩。

7 个答案:

答案 0 :(得分:2)

如果filter回调的返回值为false,则结果项将不包含在结果数组中。因为0是假的,就像NaN是假的一样,所以不包括在内。

非零,非NaN数(例如1、2、3,-1,-2,-3)不是虚假的,因此可以

要过滤出NaN的值,请考虑改用Number.isNaN

console.log([0, NaN, NaN, NaN].filter(item => !Number.isNaN(item)));
console.log([1, NaN, NaN, NaN].filter(item => !Number.isNaN(item)));
console.log([0, 1, 2, 3].filter(item => !Number.isNaN(item)));
console.log([1, 2, 3, 4].filter(item => !Number.isNaN(item)));
console.log([0.1, 0.2, 0.3, 0.4].filter(item => !Number.isNaN(item)));
console.log([1.1, 2.2, 3.3, 4.4].filter(item => !Number.isNaN(item)));
console.log([-1, -2, -3, -4].filter(item => !Number.isNaN(item)));

如果要确保该项目也是数字,请同时选中typeof

const callback = item => typeof item === 'number' && !Number.isNaN(item);

console.log([0, NaN, NaN, NaN].filter(callback));
console.log([1, NaN, NaN, NaN].filter(callback));
console.log([0, 1, 2, 3].filter(callback));
console.log([1, 2, 3, 4].filter(callback));
console.log([0.1, 0.2, 0.3, 0.4].filter(callback));
console.log([1.1, 2.2, 3.3, 4.4].filter(callback));
console.log([-1, -2, -3, -4].filter(callback));

答案 1 :(得分:2)

Array.filter

  

filter()方法创建一个具有所有通过元素的新数组   通过提供的功能实现的测试。

0NaN都是 falsey 值,因此它们被过滤器功能删除。

要过滤为0,可以使用isNaN,如下所示

console.log([0, NaN, NaN, NaN].filter(v => !isNaN(v))); // [0]

答案 2 :(得分:1)

因为0虚假

仅适用于真实值。

您可以在https://developer.mozilla.org/en-US/docs/Glossary/Truthy

中了解真实值

答案 3 :(得分:1)

这是因为有一个叫做“假”的东西。您传递了Filter函数,如果该函数为数组中的特定项目返回false或falsey值,则不会在最终数组中返回。

答案 4 :(得分:1)

传递给Array.filter的回调应该返回true或false。 Number(0)产生数字0,该数字被强制为false,这说明了为什么得到[]的原因。

答案 5 :(得分:1)

Number隐瞒了number数据类型的参数,因此它就像对实际样本数据的空操作:它们已经是number类型。过滤器只会保留真实值,而0和NaN都不真实。

您可以改用的是:

.filter(Number.isFinite)

这将排除NaN,Infinity,-Infinity和非数字数据类型的数据,但将保留所有有限数字。

如果您需要将其他数据类型(例如“ 23”之类的字符串)转换为过滤器后保留的数字,则进行链接:

.map(Number).filter(Number.isFinite)

答案 6 :(得分:1)

在过滤器函数中输入条件,数字(0)的结果为0,0为负条件(如NaN),另一方面,数字(1)为1或数字(0.1)为0.1,其中产生积极的条件。

示例:

[-1, -2, -3, -4].filter(()=>0.1);  // [ -1, -2, -3, -4 ]
[-1, -2, -3, -4].filter(()=>0));   // []
[-1, -2, -3, -4].filter(()=>NaN);  // []