Filtering array to get array of objects in ES6

Viewed 130

How do I filter the array to get the result as an array of objects?

Here's what I was trying to do

const getCars = (cars, carNames) => {
  const result = carNames.map((carName) =>
    cars.filter(
      (car) =>
      car.name === carName
    )
  );
  console.log('result', result);
  return result;
};

const cars = [{
  name: 'BMW',
  type: '2020'
}, {
  name: 'Audi',
  type: '2019'
}, {
  name: 'Benz',
  type: '2018'
}]

getCars(cars, ['BMW', 'Benz']);

I'm expecting output to be an array of objects but what I'm getting is array of arrays. Could anyone please help?

[{name: 'BMW', type: '2020'},{name: 'Benz', type: '2018'}]
2 Answers

You are getting an array of arrays because Array#map converts each element in an array to the return value of the function passed to it when called with the element. You are returning an array from the function each time, so each element is replaced with an array. Use Array#flatMap instead, which flattens the array after mapping.

const getCars = (cars, carNames) => {
  const result = carNames.flatMap((carName) =>
    cars.filter(
      (car) =>
      car.name === carName
    )
  );
  console.log('result', result);
  return result;
};

const cars = [{
  name: 'BMW',
  type: '2020'
}, {
  name: 'Audi',
  type: '2019'
}, {
  name: 'Benz',
  type: '2018'
}]

getCars(cars, ['BMW', 'Benz']);

For better efficiency, you can use Array#filter on the cars array and only keep the elements whose name is contained in the carNames array.

const getCars = (cars, carNames) => {
  const result = cars.filter(({name})=>carNames.includes(name));
  console.log('result', result);
  return result;
};

const cars = [{
  name: 'BMW',
  type: '2020'
}, {
  name: 'Audi',
  type: '2019'
}, {
  name: 'Benz',
  type: '2018'
}]

getCars(cars, ['BMW', 'Benz']);

You can merge all the arrays into one by following statement:

const merged = [].concat.apply([], getCars(cars, ['BMW', 'Benz']));

Or you can update the getCars function with the same:

const getCars = (cars, carNames) => {
  const result = carNames.map((carName) =>
    cars.filter(
      (car) =>
      car.name === carName
    )
  );
  console.log('result', result);
  return [].concat.apply([], results);
};
Related