我正在尝试从 React 中的 array.map 函数中删除重复项,但我不确定为什么我会收到"无法读取未定义的属性"错误。
下面的代码没有返回任何结果,这是我所期望的,因为 video.project.id 等于 videos[i].project.id:
this.props.videos.map((video, i, videos) => {
if (video.project.id !== videos[i].project.id) {
return (
<option
key={video.id}
value={video.project.id}
>
{video.project.projectName}
</option>
)
}
})
所以我认为下面的代码应该返回每个条目中的一个,但我反而得到错误:
this.props.videos.map((video, i, videos) => {
if (video.project.id !== videos[i - 1].project.id) {
return (
<option
key={video.id}
value={video.project.id}
>
{video.project.projectName}
</option>
)
}
})
谁能告诉我我在这里错过了什么? 或者有更好的方法来过滤它吗?
.map(( 总是返回一个相同长度的数组。默认情况下,函数将返回"未定义"。所以你的数组可能看起来像[选项组件,未定义,未定义,选项组件]等。
如果你想过滤,试着在map旁边使用Array.filter((:
this.props.videos
.filter(video => video.project.id !== this.props.videos[i - 1].project.id)
.map((video, i, videos) => {
return (
<option
key={video.id}
value={video.project.id}
>
{video.project.projectName}
</option>
)
})
此外,"无法读取未定义的属性"可能是因为索引 -1 (0 - 1( 未定义
编辑:我不确定过滤器函数中的回调是否可以解决问题。您可以使用reduce使用对象来跟踪唯一值,然后将其转换回数组:
uniqueVideos = Object.values(this.props.videos.reduce((prev, curr) => ({ ...prev, [curr.project.id]: curr }), {}))
因此地图不会过滤。它遍历每个项目,每次都返回一些内容。您可能正在寻找过滤器。我使用了普通的 for 循环,因为在这种情况下它可能更容易理解
function filterVideos(){
const ids = [];
const videoDivs = [];
for(const video of this.props.videos){
if(ids.includes(video.id)){
continue
}
ids.push(video.id);
videoDivs.push(
<option
key={video.id}
value={video.project.id}
>
{video.project.projectName}
</option>
)
}
return videoDivs
}
好的,这奏效了。 谢谢帕特里克·埃文斯,这对我来说应该是显而易见的! 我不得不在 if 语句中添加"i> 0"。
this.props.videos.map((video, i, videos) => {
if (i > 0 && video.project.id !== videos[i - 1].project.id) {
return (
<option
key={video.id}
value={video.project.id}
>{video.project.projectName}
</option>
)
}
})