使用map,filter,reduce从Arrays转换为Deeper Trees

时间:2018-06-07 05:24:42

标签: javascript

我们有4个独立的阵列,每个阵列分别包含列表,视频,boxart和书签。每个对象都有一个父ID,表示其父对象。我们想要构建一个列表对象数组,每个列表对象都有一个名称和一个视频数组。视频数组将包含视频的ID,标题,书签时间和最小的boxart网址。 使用/ debug Array.zip()作为初始要求并保留初始代码库非常重要。有人帮忙吗?

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: 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;
};    


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) {
                                return acc.width * acc.height < curr.width * curr.height ? acc : curr;
                            }),
                        function (bookmark, boxart) {
                            return { id: video.id, title: video.title, time: bookmark.time, boxart: boxart.url };
                        });
                })
    };
});

let concatArr = (function flattenDeep(arr1) {
    return arr1.reduce((acc, val) => Array.isArray(val) ? acc.concat(flattenDeep(val)) : acc.concat(val), []);
})(arr1);

console.log(concatArr)

结果

enter image description here

所需输出

enter image description here

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

    return results;
};    


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) {
                                return [acc.width * acc.height < curr.width * curr.height ? acc : curr];
                            }),
                        function (bookmark, boxart) {
                            return { id: video.id, title: video.title, time: bookmark.time, boxart: boxart.url };
                        });
                })
    };
});

    let concatArr = (function flattenDeep(arr1) {
        return arr1.reduce((acc, val) => Array.isArray(val) ? acc.concat(flattenDeep(val)) : acc.concat(val), []);
    })(arr1);

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

解决方案输出

enter image description here

enter image description here

3 个答案:

答案 0 :(得分:1)

运行时复杂性可以大大简化 - 只需将reduce timeboxart放入由视频ID索引的对象中,然后您就可以为video做同样的事情{1}}由列表ID索引:

&#13;
&#13;
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: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}];

const timeById = bookmarks.reduce((a, { videoId, time }) => {
  a[videoId] = time;
  return a;
}, {});
const boxartById = boxarts.reduce((a, { videoId, url }) => {
  a[videoId] = url;
  return a;
}, {});

const videosByListId = videos.reduce((a, { listId, id, title }) => {
  if (!a[listId]) a[listId] = [];
  a[listId].push({
    id,
    title,
    time: timeById[id],
    boxart: boxartById[id],
  });
  return a;
}, {});

const output = lists.map(({ id, name }) => ({
  name,
  videos: videosByListId[id],
}));
console.log(output);
&#13;
&#13;
&#13;

答案 1 :(得分:1)

使用mapfind使用特定密钥从数组中查找对象。

以下代码段包含评论,希望这些评论很有用

&#13;
&#13;
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: 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
    }
  ];
// using map function create an array of objects having name and videos as key. The name key will be taken from lists array and using the id from list array filter out the corrosponding objects from videos array
var newCol = lists.map(function(item) {
  return {
    names: item.name,
    videos: videos.filter(function(videoItem) {
      return item.id === videoItem.listId
    })
  }
})

// now iterate the newly created array and using its videoId , find the corrosponding objects from the boxart and bookmarks array
newCol.forEach(function(item) {
  item.videos.forEach(function(items, index) {
    let getUrl = boxarts.find(function(vidId) {
      return vidId.videoId === items.id
    })
    // update the object by adding new key videoId & time
    item.videos[index].boxarts = getUrl.url;
    let getTime = bookmarks.find(function(vidId) {
      return vidId.videoId === items.id
    });
    item.videos[index].time = getTime.time;

  })

})
console.log(newCol)
&#13;
&#13;
&#13;

答案 2 :(得分:0)

由于您有使用 zip 的要求。此解决方案使用lodash _.zipWith。解决方案不如使用reduce的那个最佳。

    let result = _.zipWith(lists, videos, boxarts, bookmarks, function(list, video, boxart, bookmark) {
      if (list === undefined) return;
      return {
        name: list.name,
        videos: videos.filter(item => item.listId === list.id).map(item => {
          return {
            id: item.id,
            title: item.title,
            boxart: boxarts.find(boxart => boxart.videoId === item.id).url,
            time: bookmarks.find(bookmark => bookmark.videoId === item.id).time
          }
        })
      }
    }).filter(item => item !== undefined) 


    console.log(result[0]);
    console.log(result[1]);