考虑电影列表
let movieLists = [{
name: "Instant Queue",
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: 150,
height: 200,
url: "http://cdn-0.nflximg.com/images/2891/BadBoys150.jpg"
}
],
"url": "http://api.netflix.com/catalog/titles/movies/70111470",
"rating": 5.0,
"bookmark": [{
id: 432534,
time: 65876586
}]
}
]
},
{
name: "New Releases",
videos: [{
"id": 65432445,
"title": "The Chamber",
"boxarts": [{
width: 150,
height: 200,
url: "http://cdn-0.nflximg.com/images/2891/TheChamber150.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: 150,
height: 200,
url: "http://cdn-0.nflximg.com/images/2891/Fracture150.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
}]
}
]
}
]
movieList由这些接口组成
interface Video {
id:number;
title:string;
boxarts:{width:number, height:number, url: string}[];
uri:string;
rating:number;
bookmark: {id:number, time:number}[];
}
interface VideoCategory {
name:string;
videos: Video[];
}
我想实现一个函数getBoxArts(),它获取类似于movieLists的类型,并为movieLists中的每个视频返回一个map {id,title,boxart},这样结果中的boxart属性就是url尺寸为150x200px的boxart对象。我只需要使用Flatmap地图和过滤器。但我无法想到的唯一方法是这样的索引:
function getBoxarts(movie) {
let res = [];
for (let i = 0; i < movie.length; i++) {
for (let j = 0; j < movie[i].videos.length; j++) {
for (let l = 0; l < movie[i].videos[j].boxarts.length; l++) {
if ((movie[i].videos[j].boxarts[l].width == 150) && (movie[i].videos[j].boxarts[l].height == 200)) {
res.push({
id: movie[i].videos[j].id,
title: movie[i].videos[j].title,
boxarts: movie[i].videos[j].boxarts[l]
});
}
}
}
}
return res;
}
代码包含3个循环,并不漂亮。
编辑:我已经定义了一个名为flatmap的函数
const concat = (x,y) =>
x.concat(y)
const flatmap = (f,xs) =>
xs.map(f).reduce(concat, [])
它的作用是获取函数f和数组A作为参数,并返回当f应用于A中的每个元素时由f返回的所有数组的串联。 例如
Flatmap((x)=>x[0], [[[1,2], [3,4]], [[5,6], [7,8]]]) => [1,2,5,6]
答案 0 :(得分:0)
您可以使用功能样式并使用array#reduce
,array#forEach
和array#find
来过滤掉boxart
150和width
200的height
。
let movieLists = [{ name: "Instant Queue", 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:150, height: 200, url: "http://cdn-0.nflximg.com/images/2891/BadBoys150.jpg" } ], "url": "http://api.netflix.com/catalog/titles/movies/70111470", "rating": 5.0, "bookmark": [{ id: 432534, time: 65876586 }] } ] }, { name: "New Releases", videos: [{ "id":65432445, "title": "The Chamber", "boxarts": [{ width: 150, height: 200, url: "http://cdn-0.nflximg.com/images/2891/TheChamber150.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: 150, height: 200, url: "http://cdn-0.nflximg.com/images/2891/Fracture150.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 }] } ] } ],
result = movieLists.reduce((r, {videos}) => {
videos.forEach(({id, title, boxarts}) => {
let boxart = boxarts.find(({width, height}) => width === 150 && height === 200);
if(boxart) {
r.push({id, title, boxarts : boxart});
}
});
return r;
}, []);
console.log(result);
您可以先展平数组,然后搜索所需的boxart
并将其推送到结果数组中。
let movieLists = [{ name: "Instant Queue", 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:150, height: 200, url: "http://cdn-0.nflximg.com/images/2891/BadBoys150.jpg" } ], "url": "http://api.netflix.com/catalog/titles/movies/70111470", "rating": 5.0, "bookmark": [{ id: 432534, time: 65876586 }] } ] }, { name: "New Releases", videos: [{ "id":65432445, "title": "The Chamber", "boxarts": [{ width: 150, height: 200, url: "http://cdn-0.nflximg.com/images/2891/TheChamber150.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: 150, height: 200, url: "http://cdn-0.nflximg.com/images/2891/Fracture150.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 }] } ] } ],
result = [].concat(...movieLists.map(({videos}) => videos))
.reduce((r,{id,title, boxarts}) => {
let boxart = boxarts.find(({width, height}) => width === 150 && height === 200);
if(boxart)
r.push({id, title, boxarts: boxart});
return r;
}, [])
console.log(result);
let movieLists = [{ name: "Instant Queue", 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:150, height: 200, url: "http://cdn-0.nflximg.com/images/2891/BadBoys150.jpg" } ], "url": "http://api.netflix.com/catalog/titles/movies/70111470", "rating": 5.0, "bookmark": [{ id: 432534, time: 65876586 }] } ] }, { name: "New Releases", videos: [{ "id":65432445, "title": "The Chamber", "boxarts": [{ width: 150, height: 200, url: "http://cdn-0.nflximg.com/images/2891/TheChamber150.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: 150, height: 200, url: "http://cdn-0.nflximg.com/images/2891/Fracture150.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 }] } ] } ],
concat = (x,y) => x.concat(y),
flatmap = (f,xs) => xs.map(f).reduce(concat, []),
result = flatmap((({videos}) => videos), movieLists)
.map(({id,title, boxarts}) => {
let boxart = boxarts.filter(({width, height}) => width === 150 && height === 200);
if(boxart || boxart.length)
return ({id, title, boxarts: boxart[0]});
else
return undefined;
})
.filter(o => o)
console.log(result);