[英]How to filter array with objects based on values in nested array and counting them
我有一个电影array
其中objects
列出每部电影的流派(作为array
)的objects
:
const movies = [
{
"title": "Movie A",
"genre": ["Action", "Sci-Fi", "Thriller"]
},
{
"title": "Movie B",
"genre": ["Horror, Sci-Fi"]
},
{
"title": "Movie C",
"genre": ["Action", "Horror", "Thriller"]
},
{
"title": "Movie D",
"genre": ["Mystery", "Horror", "Sci-Fi"]
}
];
使用(vanilla、ES6+ 或 Lodash)JavaScript:如何创建一个新array
(见下文),其中的objects
显示上面电影genre
数组中列出了多少次(下面count
)类型(下面的label
)?
换句话说:上面列出了一个类型的次数。
最终结果:按label
字母顺序排序的新array
:
const genres = [
{
"label": "Action",
"count": 2
},
{
"label": "Horror",
"count": 3
},
{
"label": "Mystery",
"count": 1
},
{
"label": "Sci-Fi",
"count": 3
},
{
"label": "Thriller",
"count": 2
}
];
您可以通过将所有genre
数组放入一个数组中,然后使用.flat()
将该数组.flat()
平来实现这一点。 之后,您可以使用.reduce
从该数组创建一个对象数组。
请参阅下面的工作示例(阅读代码注释以获取进一步说明):
const movies= [{title:"Movie A",genre:["Action","Sci-Fi","Thriller"]},{title:"Movie B",genre:["Horror","Sci-Fi"]},{title:"Movie C",genre:["Action","Horror","Thriller"]},{title:"Movie D",genre:["Mystery","Horror","Sci-Fi"]}]; res = movies.map(({genre}) => genre) // create array of genres (multi-dimensonal) .flat() // flatten the array of arrays to only have genres in it .sort((a,b) => a.localeCompare(b)) // sort the array alphabetically .reduce((acc, genre) => { let i = acc.length-1 // get the previous index of the last object let prev = acc[i]; // get the previous object if(prev && prev.label == genre) { // if the previous label is equal to the curren genre than: acc[i].count++; // add one to the current objects count } else { // otherwise... acc = [...acc, {label: genre, count: 1}]; // append a new object to the accumilator } return acc; // return the result of the accumilator to be used in next iteration }, []); // set starting value of reduce to empty array console.log(res);
或者,如果您负担不起使用.flat()
方法,您可以使用以下方法:
const movies= [{title:"Movie A",genre:["Action","Sci-Fi","Thriller"]},{title:"Movie B",genre:["Horror","Sci-Fi"]},{title:"Movie C",genre:["Action","Horror","Thriller"]},{title:"Movie D",genre:["Mystery","Horror","Sci-Fi"]}]; res = [].concat.apply([], movies.map(({genre}) => genre)) .sort((a,b) => a.localeCompare(b)) .reduce((acc, genre) => { let i = acc.length-1 let prev = acc[i]; if(prev && prev.label == genre) { acc[i].count++; } else { acc = [...acc, {label: genre, count: 1}]; } return acc; }, []); console.log(res);
这将创建带有标签和计数的数组
const movies = [ { "title": "Movie A", "genre": ["Action", "Sci-Fi", "Thriller"] }, { "title": "Movie B", "genre": ["Horror", "Sci-Fi"] }, { "title": "Movie C", "genre": ["Action", "Horror", "Thriller"] }, { "title": "Movie D", "genre": ["Mystery", "Horror", "Sci-Fi"] } ]; var genres = []; for (var i = 0; i < movies.length; i++) { var list = movies[i].genre; for (var j = 0; j < list.length; j++) { var existingValue = genres.find(function (value) { return value.label === list[j] }); if (!existingValue) { genres.push( { label: list[j], count: 1 } ); } else { existingValue.count++; } } } console.log(genres)
reduce
所有genres
放入字符串数组中sort
字符串数组进行sort
reduce
得到你需要的最终对象
counter
对象是否已经有当前genre
的label
const movies=[{title:"Movie A",genre:["Action","Sci-Fi","Thriller"]},{title:"Movie B",genre:["Horror","Sci-Fi"]},{title:"Movie C",genre:["Action","Horror","Thriller"]},{title:"Movie D",genre:["Mystery","Horror","Sci-Fi"]}]; const final = movies.reduce((genres, {genre}) => genres.concat(genre), []) .sort() .reduce((counter, genre) => { const item = counter.find(c => c.label === genre); item ? item["count"]++ : counter.push({ label:genre, count:1 }); return counter }, []); console.log(final);
或者,您可以创建一个对象,将每个genre
作为键,并将值作为最终数组中所需的对象。 然后使用Object.values
获得所需的输出:
const movies=[{title:"Movie A",genre:["Action","Sci-Fi","Thriller"]},{title:"Movie B",genre:["Horror","Sci-Fi"]},{title:"Movie C",genre:["Action","Horror","Thriller"]},{title:"Movie D",genre:["Mystery","Horror","Sci-Fi"]}]; const final = movies .map(a => a.genre) .flat() .sort() .reduce((a, label) => ((a[label] = a[label] || {label, count: 0})["count"]++,a), {}); console.log(Object.values(final));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.