在Javascript中使用Map和Filter对数组进行映射和过滤

4
这是一个非常简单的问题。我想根据另一个数组来映射和形成一个数组,然后我想删除重复的值。
这是我的做法:
let status = listHotels.map(hotel => {
  return hotel.status
})

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

它可以工作。但我希望有一种不涉及编写两个代码块的解决方案。我尝试了这个:

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

但它没有起作用。它显示:

无法读取未定义的属性'indexOf'

有人知道如何解决这个问题吗?


链接方法内不可用状态。 - David Casanellas
只有当所有链接的方法都执行完毕,并且最后一个链接方法的结果已经返回时,status 才会被赋值。因此,在链式方法中尝试在其被赋值之前访问 status 是无效的。 - ste2425
1
为什么要过滤?因为你的语句 array.indexOf(v) === i 总是会返回 true... - ChrisR
不会的,@ChrisR。这是从数组中删除重复项的常见方法。 - Blue
如果下面的任何答案回答了您的问题,那么根据本网站的工作方式,您应该“接受”该答案,更多信息请参见:***当有人回答我的问题时我该怎么做?***。但是只有在您的问题确实得到了解答时才这样做。如果没有得到解答,请考虑添加更多细节到问题中。 - Blue
4个回答

9

在调用.filter方法时,“status”仍未定义。

请将您的代码更改为:

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


2
你可以使用findIndex,传递一个用于比较状态的函数,并交换过滤器/filter和映射/map的位置来完成此操作:

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


1
status还没有准备好(undefined),无法在filter()内部访问。但在第一个解决方案中,map()返回并存储结果在status中,这使得变量在后续语句中可用。
您可以将数组本身作为第三个参数传递以在filter()中使用。您也不需要在此处使用不必要的return语句:

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


0

由于您正在使用 letconst,我假设您也可以使用 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)

将映射数组传递到Set中将确保唯一性。您可以将Set解构回数组中。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接