index 在 React array.Map 函数中没有按预期工作
index isn't working as expected in React array.Map function
我正在尝试从 React 中的 array.map 函数中删除重复项,但我不确定为什么会收到 "Cannot read property of undefined" 错误。
下面的代码没有 return 任何结果,这是我所期望的,因为 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>
)
}
})
所以我认为下面的代码应该 return 每个条目之一,但我却得到了错误:
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() 总是 returns 一个相同长度的数组。默认情况下,函数将 return 'undefined'。所以你的数组可能看起来像 [optionComponent, undefined, undefined, optionComponent] 等
如果您要过滤,请尝试在地图旁边使用 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>
)
})
此外,"Cannot read property of undefined" 可能是因为索引 -1 (0 - 1) 未定义
编辑:我不确定过滤器函数中的回调是否可以解决问题。您可以使用 reduce 来使用对象来跟踪唯一值,然后将其转回数组:
uniqueVideos = Object.values(this.props.videos.reduce((prev, curr) => ({ ...prev, [curr.project.id]: curr }), {}))
所以地图不过滤。它每次都遍历每个项目和 returns 某些东西。您可能正在寻找过滤器。我使用了一个普通的 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>
)
}
})
我正在尝试从 React 中的 array.map 函数中删除重复项,但我不确定为什么会收到 "Cannot read property of undefined" 错误。
下面的代码没有 return 任何结果,这是我所期望的,因为 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>
)
}
})
所以我认为下面的代码应该 return 每个条目之一,但我却得到了错误:
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() 总是 returns 一个相同长度的数组。默认情况下,函数将 return 'undefined'。所以你的数组可能看起来像 [optionComponent, undefined, undefined, optionComponent] 等
如果您要过滤,请尝试在地图旁边使用 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>
)
})
此外,"Cannot read property of undefined" 可能是因为索引 -1 (0 - 1) 未定义
编辑:我不确定过滤器函数中的回调是否可以解决问题。您可以使用 reduce 来使用对象来跟踪唯一值,然后将其转回数组:
uniqueVideos = Object.values(this.props.videos.reduce((prev, curr) => ({ ...prev, [curr.project.id]: curr }), {}))
所以地图不过滤。它每次都遍历每个项目和 returns 某些东西。您可能正在寻找过滤器。我使用了一个普通的 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>
)
}
})