[英]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.