Reputation: 654
I need to write a code that gets an array of integer and return an array with element increased if it's even and decreased if is odd. I tried with filter and map JavaScript functions. Here it is the code:
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);
this code prints [2, 5, 8, 13] [3, 4, 9, 12] while using a map you have
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);
this code prints [3, 4, 9, 12] [3, 4, 9, 12]
As you can see with filter the object is cloned while with map the object is changed. The documentation on MDN says:
The map() method creates a new array with the results of calling a provided function on every element in this array.
Am I using the map and filter in a wrong way or the documentation is wrong? I tested this behavior on chrome and firefox.
Actually I was using wrong the map function. Here is the map code fixed
var my_function = (some_array) => some_array.map((num) => num % 2 == 0 ? num+1 : num-1 );
Upvotes: 0
Views: 349
Reputation: 10874
You're both mutating the array through the reference passed as the third parameter in the lambda ("array") and returning a new array through the return values from the lambda. Map and filter are usually used in a functional style where the array is not mutated, but a new array is created and returned from the functions.
You want to use map here not filter. While your current filter implementation does what you want, the idiomatic way to use filter is to input one array, and return a new array which contains a subset of the elements in the first array, namely the elements that fulfill the predicate represented by the passed function.
The idiomatic way to use map is to input one array, and return a new array which has the same length as the first array, but has some function applied to each of the original elements. This is what you want, and your function should simply test for odd/even then return n-1 or n+1 respectively.
Upvotes: 2
Reputation: 672
To do what you want, you can use map like this:
var result = test.map(function(m){ return m % 2 === 0 ? m+1 : m-1 });
console.log(result);
Filter is also possible, but personally, I'd prefer map. Just keep in mind that map returns a new array with the result. Be careful not to change you original array.
Upvotes: -1
Reputation: 1292
You are using them wrong. Filter gets a function that returns a Boolean and leaves only the elements in the array for which that function returns true. What happened here is that when you used arr[i] = something you both modified the original array and returned the value "something" which evaluates to true. That's why the original array was modified and the function returned the original array without modification. The map function returns a mapping from the array to the result of the function. Since you both modified the array and returned the same value to which you modified it, you got 2 different arrays with the same values.
Upvotes: 0