Javascript 如何使用高阶函数查找在对象数组中多次出现的作者
如何使用高阶函数查找在此数组中多次出现的作者?我很确定array.filter是正确的函数,但我不知道应该设置哪个条件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:
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