Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/479.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何使用高阶函数查找在对象数组中多次出现的作者_Javascript_Arrays_Filter_Functional Programming - Fatal编程技术网

Javascript 如何使用高阶函数查找在对象数组中多次出现的作者

Javascript 如何使用高阶函数查找在对象数组中多次出现的作者,javascript,arrays,filter,functional-programming,Javascript,Arrays,Filter,Functional Programming,如何使用高阶函数查找在此数组中多次出现的作者?我很确定array.filter是正确的函数,但我不知道应该设置哪个条件 let knjige = { lektira: [{ naziv: "Zločin i kazna", autor: "Fjodor Mihajlovič Dostojevskog", br_str: 350, godina_izdavanja: 1866 }, { naziv: "Vlak u snijegu", autor:

如何使用高阶函数查找在此数组中多次出现的作者?我很确定array.filter是正确的函数,但我不知道应该设置哪个条件

let knjige = {
lektira: [{
    naziv: "Zločin i kazna",
    autor: "Fjodor Mihajlovič Dostojevskog",
    br_str: 350,
    godina_izdavanja: 1866
}, {
    naziv: "Vlak u snijegu",
    autor: "Mato Lovrak",
    br_str: 150,
    godina_izdavanja: 1931
}, {
    naziv: "Mali princ",
    autor: " Antoine de Saint-Exupery",
    br_str: 120,
    godina_izdavanja: 1943
}, {
    naziv: "Rat i mir",
    autor: "Lav Nikolajevič Tolstoj",
    br_str: 300,
    godina_izdavanja: 1865
}, {
    naziv: "Ana Karenjina",
    autor: "Lav Nikolajevič Tolstoj",
    br_str: 800,
    godina_izdavanja: 1873
}]
})


现在,您可以检查每一个图书计数,只取值较大的键。

在这种情况下,您需要的不仅仅是
过滤器。您可以从数组中提取每个作者(
map
),按作者生成计数数组(
reduce
),然后
filter
将该数组过滤为
count>1
,最后
map
条目返回到作者姓名。如果您可以使用现代JavaScript:

let autorsWithMoreThanOneBook = Object.entries(
    knjige.lektira
        .map(book => book.autor)
        .reduce((acc, autor) => {
          acc.hasOwnProperty(autor) ? acc[autor]++ : acc[autor] = 1
          return acc
        }, {})
)
   .filter(entry => entry[1] > 1)
   .map(entry => entry[0])

console.log(autorsWithMoreThanOneBook)
这些功能现在在Chrome、Firefox和Edge中都可以使用,NodeJS>=7


这实际上只是一个大的减少:获取原始数组并将其转换为具有不同结构和元素数量的对象。但是,正如我在示例中所做的那样,将其分解为管道通常更易于阅读和维护。我个人建议您使用lodash groupBy,或者您可以使用自己的reduce函数。groupBy转换类似于SQL group by。。。对象索引是group by字段的所有唯一值,这些值是具有该值的所有项

 {
  dostoyevsky: [... all the dostoyevsky books],
  king: [... all the king books],
  gogol: [...all the gogol books]
 } 
i、 e


您可以使用
sort
链接
map
以获得所有书籍的排序数组,然后
筛选
以获得副本数组,如下所示:

knjige.lektira.map(elem => elem.autor).sort()
.filter( (elem, index, array) => elem === array[index+1]  
                              && elem !== array[index-1] )

// Outputs an array of authors with more than one book
以这种方式进行过滤是因为当索引超出范围时,
undefined
会从回调返回,并且不会向过滤后的数组添加任何内容

let autorsWithMoreThanOneBook = Object.entries(
    knjige.lektira
        .map(book => book.autor)
        .reduce((acc, autor) => {
          acc.hasOwnProperty(autor) ? acc[autor]++ : acc[autor] = 1
          return acc
        }, {})
)
   .filter(entry => entry[1] > 1)
   .map(entry => entry[0])

console.log(autorsWithMoreThanOneBook)
 {
  dostoyevsky: [... all the dostoyevsky books],
  king: [... all the king books],
  gogol: [...all the gogol books]
 } 
const groupedByAuthors = _.groupBy(knjige.lektira, 'autor')
//a list of autors that appear more than once
Object.keys(groupedByAuthors).filter(key => 
groupedByAuthors[key].length > 1)
knjige.lektira.map(elem => elem.autor).sort()
.filter( (elem, index, array) => elem === array[index+1]  
                              && elem !== array[index-1] )

// Outputs an array of authors with more than one book