extract id from array using map with condition javascript

Viewed 13039

There is an array of objects

  const groups = [
    { id: 0, name: "All", selected: false },
    { id: -1, name: "All", selected: true },
    { id: 1, name: "Group1", selected: false },
    { id: 2, name: "Group2", selected: false },
    { id: 3, name: "Group3", selected: false },
    { id: 4, name: "Group4", selected: true }
  ];

I want to extract ids from this object with map

groups.map(group => group.id > 0 && group.selected ? group.id:null)

but the result will be [null,null,4,null...] actually it should be [4]

I know I can use another function like forEach and push or map and filter but I would solve it with one iteration with map or something else.

4 Answers

Filter the object/s under your criteria and then extract the id/s with a map

const groups = [{
    id: 0,
    name: "All",
    selected: false
  },
  {
    id: -1,
    name: "All",
    selected: true
  },
  {
    id: 1,
    name: "Group1",
    selected: false
  },
  {
    id: 2,
    name: "Group2",
    selected: false
  },
  {
    id: 3,
    name: "Group3",
    selected: false
  },
  {
    id: 4,
    name: "Group4",
    selected: true
  }
];


const result = groups.filter(x => x.id > 0 && x.selected).map(x => x.id)
console.log(result)

you can use a transducer in this case, so that you will not iterate through the array 2 times.

const groups = [
  { id: 0, name: "All", selected: false },
  { id: -1, name: "All", selected: true },
  { id: 1, name: "Group1", selected: false },
  { id: 2, name: "Group2", selected: false },
  { id: 3, name: "Group3", selected: false },
  { id: 4, name: "Group4", selected: true }
];

const filteredIds = groups.reduce(
  (ids, { id, selected }) => (
    id > 0 && selected ? [...ids, id] : ids
  ), []
);

console.log(filteredIds);

The map() method creates a new array with the results of calling a function for every array element and extraction is not possible with this. Either use map() and then discard the array items or use filter().

Better approach would be using filter(). The filter() method creates an array filled with all array elements that pass a test (provided as a function).

let result = groups.filter(x => x.id > 0 && x.selected).map(x => x.id)

You can easily do this in one iteration with transducers.

const getPositiveSelectedIDs = pipe([
  filter(and([
    gt(get('id'), 0),
    get('selected'),
  ])),
  map(get('id')),
])

transform(getPositiveSelectedIDs, [])(groups) // => [4]

In this example, getPositiveSelectedIDs is a transducer we declared using functions pipe, map, and filter. The predicate passed to filter uses functions and, gt, and get to say

only let groups through who have positive ids and who have been selected

then, without creating any intermediate arrays, we get the ids of each group with map and get. getPositiveSelectedIDs behaves as a transducer when we use it in transform. The flow of data starts when we call the transformation transform(getPositiveSelectedIDs, []) with groups.

More on transducers

Related