将filter()和reduce()组合成reduce()-JavaScript

时间:2018-06-14 05:58:57

标签: javascript

我们有4个独立的阵列,每个阵列分别包含列表,视频,boxart和书签。每个对象都有一个父ID,表示其父对象。我们想要构建一个列表对象数组,每个列表对象都有一个名称和一个视频数组。视频数组将包含视频的ID,标题,书签时间和最小的boxart网址。 问题:我正在尝试将boxarts.filter().reduce()合并到一个迭代中boxarts.reduce(),换句话说,将filter()合并到reduce()中。非常重要 - 使用reduce()而不是在可能的情况下更改其余代码。我试图理解reduce()的来龙去脉。有人帮忙吗?

我要重构的代码部分

[boxarts.filter(function (boxart) {
                            return boxart.videoId === video.id;
                        }).reduce(function (acc, curr) {

                            if (acc.width * acc.height < curr.width * curr.height) {
                                return acc
                            } else {
                                return curr
                            }

                            return acc
                        }, [])]

整个代码

const lists = [
    {
        "id": 5434364,
        "name": "New Releases"
    },
    {
        "id": 65456475,
        name: "Thrillers"
    }
],
    videos = [
        {
            "listId": 5434364,
            "id": 65432445,
            "title": "The Chamber"
        },
        {
            "listId": 5434364,
            "id": 675465,
            "title": "Fracture"
        },
        {
            "listId": 65456475,
            "id": 70111470,
            "title": "Die Hard"
        },
        {
            "listId": 65456475,
            "id": 654356453,
            "title": "Bad Boys"
        }
    ],
    boxarts = [
        { videoId: 65432445, width: 130, height: 200, url: "http://cdn-0.nflximg.com/images/2891/TheChamber130.jpg" },
        { videoId: 65432445, width: 200, height: 200, url: "http://cdn-0.nflximg.com/images/2891/TheChamber200.jpg" },
        { videoId: 675465, width: 200, height: 200, url: "http://cdn-0.nflximg.com/images/2891/Fracture200.jpg" },
        { videoId: 675465, width: 120, height: 200, url: "http://cdn-0.nflximg.com/images/2891/Fracture120.jpg" },
        { videoId: 675465, width: 300, height: 200, url: "http://cdn-0.nflximg.com/images/2891/Fracture300.jpg" },
        { videoId: 70111470, width: 150, height: 200, url: "http://cdn-0.nflximg.com/images/2891/DieHard150.jpg" },
        { videoId: 70111470, width: 300, height: 200, url: "http://cdn-0.nflximg.com/images/2891/DieHard300.jpg" },
        { videoId: 70111470, width: 200, height: 200, url: "http://cdn-0.nflximg.com/images/2891/DieHard200.jpg" },
        { videoId: 654356453, width: 200, height: 200, url: "http://cdn-0.nflximg.com/images/2891/BadBoys200.jpg" },
        { videoId: 654356453, width: 140, height: 200, url: "http://cdn-0.nflximg.com/images/2891/BadBoys140.jpg" }
    ],
    bookmarks = [
        { videoId: 65432445, time: 32432 },
        { videoId: 675465, time: 3534543 },
        { videoId: 70111470, time: 645243 },
        { videoId: 654356453, time: 984934 }
    ];

Array.zip = function (bookmark, boxart, combinerFunction) {
    let counter,
        results = [];

    for (counter = 0; counter < Math.min(bookmark.length, boxart.length); counter++) {
        results.push(combinerFunction(bookmark[counter], boxart[counter]));
    }

    return results;
};


// Kick off the timer
console.time('filter.reduce');

let arr1 = lists.map(function (list) {
    return {
        name: list.name,
        videos:
            videos.
                filter(function (video) {
                    return video.listId === list.id;
                }).
                map(function (video) {
                    return Array.zip(
                        bookmarks.filter(function (bookmark) {
                            return bookmark.videoId === video.id;
                        }),
                        [boxarts.filter(function (boxart) {
                            return boxart.videoId === video.id;
                        }).reduce(function (acc, curr) {

                            if (acc.width * acc.height < curr.width * curr.height) {
                                return acc
                            } else {
                                return curr
                            }

                            return acc
                        }, [])],
                        function (bookmark, boxart) {
                            return { id: video.id, title: video.title, time: bookmark.time, boxart: boxart.url };
                        });
                })
    };
});

// End the timer, get the elapsed time
console.timeEnd('filter.reduce');

// //to enable deep level flatten use recursion with reduce and concat
let concatArr1 = (function flattenDeep(arr1) {
    return arr1.reduce((acc, val) => Array.isArray(val) ? acc.concat(flattenDeep(val)) : acc.concat(val), []);
})(arr1);

console.log(JSON.stringify(concatArr1, null, 2))

所需输出

enter image description here

 let arr1 = lists.map(function (list) {
    return {
        name: list.name,
        videos:
            videos.
                filter(function (video) {
                    return video.listId === list.id;
                }).
                map(function (video) {
                    return Array.zip(
                        bookmarks.filter(function (bookmark) {
                            return bookmark.videoId === video.id;
                        }),
                        [boxarts.reduce(function (acc, curr) {
                            if (curr.videoId === video.id) {
                                if (acc.width * acc.height < curr.width * curr.height) {
                                    return acc
                                } else {
                                    return curr
                                }
                            }

                            return acc
                        }, [])],
                        function (bookmark, boxart) {
                            return { id: video.id, title: video.title, time: bookmark.time, boxart: boxart.url };
                        });
                })
    };
});

2 个答案:

答案 0 :(得分:1)

您可以尝试以下操作,基本上使用Array.reduce创建相关属性的地图,然后使用Array.map最终映射生成的地图:

&#13;
&#13;
const lists = [{"id":5434364,"name":"New Releases"},{"id":65456475,"name":"Thrillers"}];
const  videos = [{"listId":5434364,"id":65432445,"title":"The Chamber"},{"listId":5434364,"id":675465,"title":"Fracture"},{"listId":65456475,"id":70111470,"title":"Die Hard"},{"listId":65456475,"id":654356453,"title":"Bad Boys"}];
const boxarts =[{"videoId":65432445,"width":130,"height":200,"url":"http://cdn-0.nflximg.com/images/2891/TheChamber130.jpg"},{"videoId":65432445,"width":200,"height":200,"url":"http://cdn-0.nflximg.com/images/2891/TheChamber200.jpg"},{"videoId":675465,"width":200,"height":200,"url":"http://cdn-0.nflximg.com/images/2891/Fracture200.jpg"},{"videoId":675465,"width":120,"height":200,"url":"http://cdn-0.nflximg.com/images/2891/Fracture120.jpg"},{"videoId":675465,"width":300,"height":200,"url":"http://cdn-0.nflximg.com/images/2891/Fracture300.jpg"},{"videoId":70111470,"width":150,"height":200,"url":"http://cdn-0.nflximg.com/images/2891/DieHard150.jpg"},{"videoId":70111470,"width":300,"height":200,"url":"http://cdn-0.nflximg.com/images/2891/DieHard300.jpg"},{"videoId":70111470,"width":200,"height":200,"url":"http://cdn-0.nflximg.com/images/2891/DieHard200.jpg"},{"videoId":654356453,"width":200,"height":200,"url":"http://cdn-0.nflximg.com/images/2891/BadBoys200.jpg"},{"videoId":654356453,"width":140,"height":200,"url":"http://cdn-0.nflximg.com/images/2891/BadBoys140.jpg"}];
const bookmarks = [{"videoId":65432445,"time":32432},{"videoId":675465,"time":3534543},{"videoId":70111470,"time":645243},{"videoId":654356453,"time":984934}];
   
const bookmarksMap = bookmarks.reduce((a,obj)=>{
    a[obj.videoId] = {
      "time" : obj.time
    };
    return a;
},{});
const boxartsMap = boxarts.reduce((a,obj)=>{
    if(!a[obj.videoId] || a[obj.videoId].min > (obj.width*obj.height)){
       a[obj.videoId] = {
        "boxart" : obj.url,
         "min" : (obj.width*obj.height)
        } 
      } 
    return a;
},{});
    
const videosMap = videos.reduce((a,obj)=>{
  if(!a[obj.listId]){
    a[obj.listId] = [];
  }  
  a[obj.listId].push({
    "id" : obj.id,
    "title" : obj.title,
    "time" : bookmarksMap[obj.id].time,
    "boxart" : boxartsMap[obj.id].boxart
  });
    return a;
},{});
const result = lists.map((o)=>{
    var obj = {
    "name" : o.name, 
    "videos" : videosMap[o.id]
    };
    return obj;
 });
console.log(result);
&#13;
&#13;
&#13;

答案 1 :(得分:0)

您可以使用以下数组方法获得所需的结果

  • reduce()

  • filter()

  • find()

  • map()

  • push()

演示

&#13;
&#13;
let lists = [{"id": 5434364,"name": "New Releases"}, {"id": 65456475,name: "Thrillers"}],
    videos = [{"listId": 5434364,"id": 65432445,"title": "The Chamber"}, {"listId": 5434364,"id": 675465,"title": "Fracture"}, {"listId": 65456475,"id": 70111470,"title": "Die Hard"}, {"listId": 65456475,"id": 654356453,"title": "Bad Boys"}],
    boxarts = [{videoId: 65432445,width: 130,height: 200,url: "http://cdn-0.nflximg.com/images/2891/TheChamber130.jpg"}, {videoId: 65432445,width: 200,height: 200,url: "http://cdn-0.nflximg.com/images/2891/TheChamber200.jpg"},{videoId: 675465,width: 200,height: 200,url: "http://cdn-0.nflximg.com/images/2891/Fracture200.jpg"},{videoId: 675465,width: 120,height: 200,url: "http://cdn-0.nflximg.com/images/2891/Fracture120.jpg"},{videoId: 675465,width: 300,height: 200,url: "http://cdn-0.nflximg.com/images/2891/Fracture300.jpg"},{videoId: 70111470,width: 150,height: 200,url: "http://cdn-0.nflximg.com/images/2891/DieHard150.jpg"},{videoId: 70111470,width: 300,height: 200,url: "http://cdn-0.nflximg.com/images/2891/DieHard300.jpg"},{videoId: 70111470,width: 200,height: 200,url: "http://cdn-0.nflximg.com/images/2891/DieHard200.jpg"},{videoId: 654356453,width: 200,height: 200,url: "http://cdn-0.nflximg.com/images/2891/BadBoys200.jpg"},{videoId: 654356453,width: 140,height: 200,url: "http://cdn-0.nflximg.com/images/2891/BadBoys140.jpg"}],
    bookmarks = [{videoId: 65432445,time: 32432},{videoId: 675465,time: 3534543},{videoId: 70111470,time: 645243},{videoId: 654356453,time: 984934}];

let res = lists.reduce((r, o) => {
    let filtrArr = videos.filter(({listId}) => listId == o.id);
  
    let result = filtrArr.map(item => {
        let find = boxarts.filter(({videoId}) => videoId == item.id);

        find = (find || []).sort((a, b) => a.width > b.width)[0];
        item.boxarts = find ? find.url : '';
        
      	find = bookmarks.find(({videoId}) => videoId == item.id);
        item.time = find.time || '';
        
        return item;
    });
  
    r.push({
        name: o.name,
        videos: result
    })
    return r;
}, [])

console.log(res)
&#13;
.as-console-wrapper {max-height: 100% !important;top: 0;}
&#13;
&#13;
&#13;