Jeff Goes
Jeff Goes

Reputation: 555

Map and Filter mapped array in Javascript

This a very simple question. I want to map and form an array given another array. then I would like to remove the duplicated values.

this is what I did:

let status = listHotels.map(hotel => {
  return hotel.status
})

const x = status.filter((v, i) => (
  status.indexOf(v) === i
));

It works. But I would like a solution that doesn't involve writing two blocks of code. I tried this:

let status = listHotels.map(hotel => {
  return hotel.status
}).filter((v, i) => (
  status.indexOf(v) === i
));

But it didnt work. It says

Cannot read property 'indexOf' of undefined

Does anyone know a workaround this?

Upvotes: 4

Views: 9129

Answers (4)

Karim
Karim

Reputation: 8632

status is still not defined when you call the .filter method.

change your code to:

const listHotels = [{status:'s1'}, {status:'s1'}, {status:'s2'}]
let status = listHotels.map(hotel => {
  return hotel.status
}).filter((v, i, currentStatus) => (
  currentStatus.indexOf(v) === i
));
console.log(status);

Upvotes: 9

Mamun
Mamun

Reputation: 68933

status is not ready yet (undefined) to access inside the filter(). But in the first solution, map() returns and stores result in status which makes the variable available in the later statements.

You can pass the array itself as the third parameter to use in the filter(). You also do not need to use unnecessary return statement here:

var listHotels = [{status:'a'}, {status:'b'}, {status:'a'}]

let status = listHotels.map(hotel => hotel.status)
                       .filter((v, i, arr) => arr.indexOf(v) === i);
console.log(status);

Upvotes: 1

chazsolo
chazsolo

Reputation: 8439

Since you are using let and const I'm assuming you can also use ES6 Set:

const data = [{
  status: 'one',
  id: 1
}, {
  status: 'one',
  id: 2
}, {
  status: 'two',
  id: 3
}, {
  status: 'two',
  id: 4
}]

const uniqueStatus = [...new Set(data.map(({
  status
}) => status))]

console.log(uniqueStatus)

Passing the mapped array into Set will ensure uniqueness. You can destructure the Set back into an array.

Upvotes: 1

Blue
Blue

Reputation: 22911

You can do this using findIndex, passing a function to compare statuses, and swapping filter/map around:

const listHotels = [{status: 'bad'}, {status: 'good'}, {status: 'bad'}];

let status = listHotels.filter((v, i) =>
  listHotels.findIndex(v2 => v.status === v2.status) === i
).map(hotel => hotel.status);

console.log(status);

Upvotes: 2

Related Questions