简体   繁体   中英

JavaScript: Why can't I chain after my nested reduce function?

How do I go up a level and return "id and title" pairs to my array? I get an error when trying to use map after my reduce function.

Array.prototype.mergeAll = function(){
    return [].concat.apply([], this);
};

Array.prototype.flatMap = function(func){
    return this.map(function(item){
        return func(item);
    }).mergeAll();
};

function test() {
    var movieLists = [
        {
            name: "New Releases",
            videos: [
                {
                    "id": 70111470,
                    "title": "Die Hard",
                    "boxarts": [
                        { width: 150, height:200, url:"http://cdn-0.nflximg.com/images/2891/DieHard150.jpg" },
                        { width: 200, height:200, url:"http://cdn-0.nflximg.com/images/2891/DieHard200.jpg" }
                    ],
                    "url": "http://api.netflix.com/catalog/titles/movies/70111470",
                    "rating": 4.0,
                    "bookmark": []
                },
                {
                    "id": 654356453,
                    "title": "Bad Boys",
                    "boxarts": [
                        { width: 200, height:200, url:"http://cdn-0.nflximg.com/images/2891/BadBoys200.jpg" },
                        { width: 140, height:200, url:"http://cdn-0.nflximg.com/images/2891/BadBoys140.jpg" }

                    ],
                    "url": "http://api.netflix.com/catalog/titles/movies/70111470",
                    "rating": 5.0,
                    "bookmark": [{ id:432534, time:65876586 }]
                }
            ]
        },
        {
            name: "Thrillers",   
            videos: [
                {
                    "id": 65432445,
                    "title": "The Chamber",
                    "boxarts": [
                        { width: 130, height:200, url:"http://cdn-0.nflximg.com/images/2891/TheChamber130.jpg" },
                        { width: 200, height:200, url:"http://cdn-0.nflximg.com/images/2891/TheChamber200.jpg" }
                    ],
                    "url": "http://api.netflix.com/catalog/titles/movies/70111470",
                    "rating": 4.0,
                    "bookmark": []
                },
                {
                    "id": 675465,
                    "title": "Fracture",
                    "boxarts": [
                        { width: 200, height:200, url:"http://cdn-0.nflximg.com/images/2891/Fracture200.jpg" },
                        { width: 120, height:200, url:"http://cdn-0.nflximg.com/images/2891/Fracture120.jpg" },
                        { width: 300, height:200, url:"http://cdn-0.nflximg.com/images/2891/Fracture300.jpg" }
                    ],
                    "url": "http://api.netflix.com/catalog/titles/movies/70111470",
                    "rating": 5.0,
                    "bookmark": [{ id:432534, time:65876586 }]
                }
            ]
        }
    ];


    // Use one or more flatMap, map, and reduce calls to create an array with the following items (order doesn't matter)
    // [
    //     {"id": 675465,"title": "Fracture","boxart":"http://cdn-0.nflximg.com/images/2891/Fracture120.jpg" },
    //     {"id": 65432445,"title": "The Chamber","boxart":"http://cdn-0.nflximg.com/images/2891/TheChamber130.jpg" },                
    //     {"id": 654356453,"title": "Bad Boys","boxart":"http://cdn-0.nflximg.com/images/2891/BadBoys140.jpg" },
    //     {"id": 70111470,"title": "Die Hard","boxart":"http://cdn-0.nflximg.com/images/2891/DieHard150.jpg" }                
    // ];

    return movieLists.flatMap(function(movieList) {
            return movieList.videos.flatMap(function(vids){
                    return vids.boxarts.reduce(function(a,b){
                        if (a.width * a.height < b.width * b.height) return a;
                        else return b;                
                    });
            });
    });
}
test();

// this is what gets returned... I want to add higher level object properties also. Specifically ID and Title.

=> [ { width: 150,
    height: 200,
    url: 'http://cdn-0.nflximg.com/images/2891/DieHard150.jpg' },
  { width: 140,
    height: 200,
    url: 'http://cdn-0.nflximg.com/images/2891/BadBoys140.jpg' },
  { width: 130,
    height: 200,
    url: 'http://cdn-0.nflximg.com/images/2891/TheChamber130.jpg' },
  { width: 120,
    height: 200,
    url: 'http://cdn-0.nflximg.com/images/2891/Fracture120.jpg' } ]

Here's a version that I think will work:

return movieLists.flatMap(function (movieList) {
    return movieList.videos.flatMap(function (vids) {
        return { 
            id: vids.id,
            title: vids.title,
            boxart: vids.boxarts.reduce(function (a, b) {
                if (a.width * a.height < b.width * b.height) return a;
                else return b;
            }).url
        }
    });
});

You have access to the video info in that inner flatmap call, so this is where you need to construct your custom returned object that has the id and title. It might be clearer to rename the vids parameter to video or something. I Hope this helps! Let me know if you need any clarification.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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