I have filter and map function chained. I need to do something conditional on whether a filter returns an empty array or not. However the map function on the array does not seem to be invoked if the filter returns an empty array.
const letters = ["a", "b", "c"];
const numbers = [1, 2, 3]
function result (arr) {
arr.filter((x) => {return x === "a"}).map((y, i, arr) => {
if(arr.length === 0) {
return (document.getElementById("p").innerHTML = "empty")
} else {
return (document.getElementById("p").innerHTML = "found it")
}})
}
Is this expected or am I doing something wrong?
I was expecting the filter result to be passed to the map function, which can be used as the 3rd argument of the map function: map(item, index, array)
Here's a JSFiddle of the problem https://jsfiddle.net/sub3z0xh/
CodePudding user response:
You’re right about what’s happening. Array methods run once per element in the source array. If the source array is empty, it doesn’t run.
This isn’t new or working different with array methods vs a basic for loop. Example:
const arr = [];
for (let i = 0; i < arr.length; i ) {
console.log(“this code never runs because there are no elements to loop”);
}
So maybe just store the result of the filter in a variable instead. Get rid of the chained map since it may not run. Check the size/contents of your filtered array, then do stuff with that.
CodePudding user response:
This behavior is as expected.
Array iterator methods, including .map
, filter
, .forEach
, .reduce
and the like, take function arguments that are called with the value of successive array entries. If the array has no entries, the iterator methods make no calls to their function argument.
Try writing the test function to take the array it wants to check as argument, call it with the array chain that produces the array to test, and have the function return its argument for further chaining.
The alternative is to not write the test as a one liner.