Reputation: 4337
I'm transforming my array with Array.prototype.map()
, and if the current item matches some conditions, I want to change its previous item.
The code below seems not working, how do I do it without a for
loop?
var nums = [1, 2, 3, 4, 5];
var res = nums.map((item, index, array) => {
if (item > 3) {
array[index - 1] += 1;
}
return item;
});
console.log(res); // [ 1, 2, 3, 4, 5 ], I want [1, 2, 4, 5, 5]
Upvotes: 2
Views: 2381
Reputation: 23372
Disclaimer: this answer is only here because I feel whenever somebody asks "how do I do X without a for loop", I feel there should at least be one recursive solution between all the maps and reduces :)
how do I do it without a for loop?
If you don't care much about performance or the risk of blowing the stack, you can go with a recursive function!
Here's an example:
first
, second
and the restfirst
is empty, we've reached the end of our computation and return the resultfirst
is not empty, we can compare it to second
to determine its value. We add the value to our result and recurse:[second, ...rest]
and passing along our resultconst input = [ 1, 2, 3, 4, 5 ];
const Empty = Symbol();
const incIfBt3 =
([first = Empty, second, ...rest], result = []) =>
first === Empty
? result
: incIfBt3(
[second, ...rest],
[...result, first + (second > 3)]
);
console.log(incIfBt3(input));
Upvotes: 1
Reputation: 122956
You can use a reducer
var res = [1, 2, 3, 4, 5]
.reduce((reduced, item, i) => {
i && (reduced[i-1] += item > 3 ? 1 : 0);
return [...reduced, item];
}, []);
console.log(res);
Upvotes: 2
Reputation: 101738
Instead of trying to change the previous item, you can use the array
parameter to look at the next item and return a value for the current item accordingly:
var nums = [1, 2, 3, 4, 5];
var res = nums.map((item, index, array) => item + (array[index + 1] > 3 ? 1 : 0));
console.log(res); // [1, 2, 4, 5, 5]
You can also take advantage of the fact that the numeric value of a boolean is either 1 or 0 to eliminate the conditional expression:
var nums = [1, 2, 3, 4, 5];
var res = nums.map((item, index, array) => item + (array[index + 1] > 3));
console.log(res); // [1, 2, 4, 5, 5]
Upvotes: 0
Reputation: 2075
You can look ahead instead of trying to look behind:
var nums = [1, 2, 3, 4, 5];
var res = nums.map((item, index, array) => {
if (array[index + 1] > 3) {
item += 1;
}
return item;
});
Upvotes: 0
Reputation: 371049
Arrays that are in the process of being created from .map
can't be referenced like that. Instead, create the array outside of the forEach
, and push to / assign to it:
var nums = [1, 2, 3, 4, 5];
const newArr = [];
nums.forEach((item, index) => {
if (item > 3) newArr[index - 1] += 1;
newArr.push(item);
});
console.log(newArr); // I want [1, 2, 4, 5, 5]
Upvotes: 1