7

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.

3
  • The map() method creates a new array populated with the results of calling a provided function on every element in the calling array. That is why you are getting null for those fields which does not satisfies the condition. Instead use filter
    – brk
    Commented Mar 12, 2020 at 11:22
  • @brk you mean there is no way to avoid returning value in map? Commented Mar 12, 2020 at 11:25
  • "I want to bang this nail into a wall. I know I can use a hammer, but I want to use my shoe". Do you see the problem? You're using the wrong tool for the job. Why do you think you need to use map specifically? It looks like a combination of filter and map is what you should be using as per one of the answers below.
    – Jamiec
    Commented Mar 12, 2020 at 11:30

4 Answers 4

5

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)

7
  • thanks @eugen-sunic , is there any way to avoid returning value in map. Commented Mar 12, 2020 at 11:27
  • the point of map is to return something to you array, what do you want exactly?
    – EugenSunic
    Commented Mar 12, 2020 at 11:28
  • What I want and why I ask this question was to find a way to return nothing or void return value in some condition in map function. Commented Mar 12, 2020 at 11:33
  • 1
    @HamidShoja anyways if your issue is to use filter and achieve this with a map then that's not possible and should not be done that way either.. you should first filter and then extract otherwise you want something else
    – EugenSunic
    Commented Mar 12, 2020 at 11:36
  • 1
    Ok thanks, so the map function always returns a value and it's unavoidable. Commented Mar 12, 2020 at 11:37
1

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);

1
  • 1
    your solution certainly has the performance benefits of a transducer solution, but it is not exactly the same.
    – richytong
    Commented May 23, 2020 at 3:41
0

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)

0

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.