简体   繁体   English

索引无法在React array.Map函数中按预期工作

[英]index isn't working as expected in React array.Map function

I'm trying to remove the duplicates from an array.map function in React and I'm not sure why I'm getting a "Cannot read property of undefined" error. 我正在尝试从React中的array.map函数中删除重复项,但不确定为什么会出现“无法读取未定义的属性”错误。

The below code does not return any results, which is what I expected because video.project.id is equal to videos[i].project.id: 以下代码未返回任何结果,这是我期望的结果,因为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>
        )
    }
})

So I would think the below code should return one of each entry but I instead get the error: 所以我认为下面的代码应该返回每个条目之一,但是我却得到了错误:

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

Can anyone tell me what I'm missing here? 谁能告诉我我在这里想念的东西吗? Or is there a better way to filter this? 还是有更好的方法进行过滤?

.map() always returns an array of same length. .map()始终返回相同长度的数组。 Functions will return 'undefined' by default. 默认情况下,函数将返回“未定义”。 So your array might look like [optionComponent, undefined, undefined, optionComponent] etc. 因此,您的数组可能看起来像[optionComponent,undefined,undefined,optionComponent]等。

If you're looking to filter, try using Array.filter() alongside the 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>
        )
})

Also, "Cannot read property of undefined" might be because index -1 (0 - 1) is undefined 另外,“无法读取未定义的属性”可能是因为未定义索引-1(0-1)

Edit: I'm not sure that callback in the filter function would do the trick though. 编辑:我不确定过滤器函数中的回调是否可以解决问题。 You could use reduce to use an object to keep track of unique values, then turn that back into an array: 您可以使用reduce来使用对象来跟踪唯一值,然后将其返回为数组:

uniqueVideos = Object.values(this.props.videos.reduce((prev, curr) => ({ ...prev, [curr.project.id]: curr }), {}))

So a map doesn't filter. 因此,地图不会过滤。 It iterates over each item and returns something every time. 它遍历每个项目并每次都返回一些东西。 You might be looking for a filter. 您可能正在寻找过滤器。 I used a plain for loop because it might be more understandable in this scenario 我使用了普通的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
}

Ok this worked. 好的,这可行。 Thank you Patrick Evans, this should have been obvious to me! 谢谢Patrick Evans,这对我来说应该很明显! I had to add "i > 0" to the if statement. 我必须在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>
        )
    }
})

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM