如何根据嵌套数组中的值过滤对象数组并对其进行计数

时间:2018-12-23 11:58:02

标签: javascript arrays sorting extract

我有一部电影array,其中objects列出了每部电影的类型(作为array):

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"]
    }
];

使用(香草,ES6 +或Lodash)JavaScript:如何创建新的array(见下文),其中objects显示多少次(以下count)一个流派(下面的label)是否在上面的电影 genre数组中列出?

换句话说:上面列出了一种类型的次数。

最终结果:一个新的array,按label的字母顺序排列:

const genres = [
    {
        "label": "Action",
        "count": 2
    },
    {
        "label": "Horror",
        "count": 3
    },
    {
        "label": "Mystery",
        "count": 1
    },
    {
        "label": "Sci-Fi",
        "count": 3
    },
    {
        "label": "Thriller",
        "count": 2
    }
];

3 个答案:

答案 0 :(得分:1)

您可以通过将所有genre数组放入数组,然后使用.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);

答案 1 :(得分:1)

这将创建带有标签和计数的数组

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)

答案 2 :(得分:1)

  • 使用reduce将所有genres放入字符串数组
  • sort字符串数组
  • 使用reduce获取所需的最终对象
    • 在此范围内,检查counter对象是否已具有用于当前label的{​​{1}}
    • 如果是,则将其递增,否则将新对象添加到数组中

genre

或者您可以创建一个对象,其中每个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