1

I was writing some code and something puzzled me. I have an array of numbers called alarmsList. Now I wish to iterate through this list and if a value is higher than 60 for example I want to create a new object array (collection) where we store the high value and it's index from the original array. So take the following code

const alarmsList = [1, 61, 77, 4, 5, 6, 7, 8, 85, 4, 3, 55];

const highAlarmsList = alarmsList.map((item, index) => {
    if(item > 60) {
        return ({ value: item, index })
    }
});

console.log(highAlarmsList)

The console.log outputs the following

[
    undefined,
    {
        "value": 61,
        "index": 1
    },
    {
        "value": 77,
        "index": 2
    },
    undefined,
    undefined,
    undefined,
    undefined,
    undefined,
    {
        "value": 85,
        "index": 8
    },
    undefined,
    undefined,
    undefined
]

This output is what I require but how do I prevent the undefined values being returned? I thought about using array.filter but that doesn't seem appropriate? Should I use a different array method? I don't want to use a for loop and push to a new array unless that is the best/only way to achieve the new array without the undefined values being returned.

NewToAngular
  • 975
  • 2
  • 13
  • 23
  • 2
    Yes, `.filter()` would be appropriate here, but that will involve an additional pass over your array/filtered array. There is also `.reduce()`, which you could use to do the filtering and mapping at the same time, or `.flatMap()`, but these aren't usually as readable as a for loop or filter + map (see: [Map and filter an array at the same time](https://stackoverflow.com/q/34398279)) – Nick Parsons Oct 16 '21 at 08:45

2 Answers2

2

You can use Array.filter() to removing the undefined values by using Boolean as the predicate:

const alarmsList = [1, 61, 77, 4, 5, 6, 7, 8, 85, 4, 3, 55];

const highAlarmsList = alarmsList.map((item, index) => {
  if(item > 60) {
    return ({ value: item, index })
  }
}).filter(Boolean);

console.log(highAlarmsList)

You can use Array.flatMap() and return empty arrays instead of undefined, but that might effect performance for huge arrays:

const alarmsList = [1, 61, 77, 4, 5, 6, 7, 8, 85, 4, 3, 55];

const highAlarmsList = alarmsList.flatMap((item, index) => 
  item > 60 ? { value: item, index } : []
);

console.log(highAlarmsList)
Ori Drori
  • 183,571
  • 29
  • 224
  • 209
0

map creates a new array by running the callback on every element of the array. If the condition does not satisfy it will return undefined or null. So it not possible to skip the element from the output.

Alternatively you can ue reduce or filter

const alarmsList = [1, 61, 77, 4, 5, 6, 7, 8, 85, 4, 3, 55];

const highAlarmsList = alarmsList.reduce((acc, item, index) => {
  item > 60 && acc.push({
    value: item,
    index
  })
  return acc;
}, [])

console.log(highAlarmsList)
brk
  • 48,835
  • 10
  • 56
  • 78