javascript 中过滤器和地图的奇怪行为

Strange behavior of filter and map in javascript

我需要编写一个代码来获取一个整数数组和 return 一个元素为偶数则增加,如果元素为奇数则减少的数组。 我尝试使用 filter 和 map JavaScript 函数。这是代码:

var test=[2,5,8,13];
var my_function = (some_array) => some_array.filter((num,index,array) => num % 2 == 0 ? array[index]=num+1 : array[index]=num-1 );
console.log(my_function(test));
console.log(test);

此代码打印 [2, 5, 8, 13] [3, 4, 9, 12] 使用地图时你有

var test=[2,5,8,13];

var my_function = (some_array) => some_array.map((num,index,array) => num % 2 == 0 ? array[index]=num+1 : array[index]=num-1 );
console.log(my_function(test));
console.log(test);

此代码打印 [3, 4, 9, 12] [3, 4, 9, 12]

正如您所看到的,使用 filter 对象被克隆,而使用 map 对象被更改。 MDN 上的文档说:

map() 方法使用对该数组中每个元素调用提供的函数的结果创建一个新数组。

我是不是以错误的方式使用了地图和过滤器,或者文档有误? 我在 chrome 和 firefox 上测试了这种行为。

其实我用错了地图功能。这是固定的地图代码

var my_function = (some_array) => some_array.map((num) => num % 2 == 0 ? num+1 : num-1 );

你用错了。 Filter 获取一个 returns 布尔值的函数,并仅保留数组中该函数 returns 为真的元素。这里发生的事情是,当您使用 arr[i] = something 时,您既修改了原始数组又返回了计算结果为 true 的值 "something"。这就是为什么原始数组被修改并且函数返回原始数组而不修改的原因。 map函数returns 一个从数组到函数结果的映射。由于您都修改了数组并返回了修改后的相同值,因此您得到了 2 个具有相同值的不同数组。

你们都通过在 lambda ("array") 中作为第三个参数传递的引用来改变数组,并且 return 通过来自拉姆达。 Map 和 filter 通常用于函数式样式,其中数组不会发生变化,但会创建一个新数组并从函数中 returned。

您想在这里使用地图而不是过滤器。虽然您当前的过滤器实现可以满足您的需求,但使用过滤器的惯用方法是输入一个数组,然后 return 一个新数组,其中包含第一个数组中元素的子集,即满足谓词的元素由传递的函数表示。

使用 map 的惯用方法是输入一个数组,然后 return 一个与第一个数组长度相同的新数组,但对每个原始元素应用了一些函数。这就是您想要的,您的函数应该分别测试 odd/even 然后 return n-1 或 n+1。

做你想做的事,你可以像这样使用 map

var result = test.map(function(m){ return m % 2 === 0 ? m+1 : m-1 });
console.log(result);

过滤器也可以,但就我个人而言,我更喜欢地图。请记住 map returns 一个 new 数组和结果。注意不要更改原始数组。