曾经看过类似的话题,但无法将我的头缠住。即使对我来说,我当前的项目似乎也更复杂。这是我的json(抱歉,它有点长):
items = [
{
'name' : 'Books',
'types':[
{
'name' : 'Hard Cover',
'genres':[
{
'genre' : 'Romance',
'added_date' : '2018-09-15',
'id':1
},
{
'genre' : 'Crime',
'added_date' : '2018-10-01',
'id' : 2
}
],
'cover':['pic1.png','pic2.png']
},
{
'name' : 'Audio',
'genres':[
{
'genre' : 'Memoir',
'added_date' : '2018-08-01',
'id' : 3
}
],
'pictures':['pic3.png','pic4.png']
},
]
},
{
'name' : 'Videos',
'types':[
{
'name' : 'English',
'genres':[
{
'genre' : 'Comedy',
'added_date' : '2018-10-14',
'id' : 12
}
],
'pictures':['pic5.png','pic6.png']
}
]
}
];
我现在想要的输出是根据流派块中的added_date字段获取最近添加的3个项目。现在,对于这些项目,我需要返回带有完整路径的字典元素的数组:
[
{'id':7,'genre':'Romance','name':'Hard Cover','added_date':'2018-09-16','top_parent_name':'Books'},
{'id':8,'genre':'Memoir','name':'Audio','added_date':'2018-09-15','top_parent_name':'Books'},
]
基于add_date,获取通过整个对象及其相关信息添加的最新3个项目。我希望这是有道理的。
到目前为止,我已经想到了以下内容,但很快就变得很麻烦。
items.forEach(function(value, index, array) {
const types: any[] = value['types'];
types.forEach(function(value_t, index_t, array_t){
const genres: any[] = value_model['genes'];
//loop again to get date....
});
});
答案 0 :(得分:3)
这是一种方法。首先,通过执行多个级别的映射然后进行多个级别的扁平化,将所需的数据提取到对象中。 (我相信Array.prototype.flatten
尚不普及,所以我使用reduce(concat)
。)
然后,当您将数据提取到平面列表中时,将其按日期降序排序。最后,获取前三个值:
const items = [{"name": "Books", "types": [{"cover": ["pic1.png", "pic2.png"], "genres": [{"added_date": "2018-09-15", "genre": "Romance", "id": 1}, {"added_date": "2018-10-01", "genre": "Crime", "id": 2}], "name": "Hard Cover"}, {"genres": [{"added_date": "2018-08-01", "genre": "Memoir", "id": 3}], "name": "Audio", "pictures": ["pic3.png", "pic4.png"]}]}, {"name": "Videos", "types": [{"genres": [{"added_date": "2018-10-14", "genre": "Comedy", "id": 12}], "name": "English", "pictures": ["pic5.png", "pic6.png"]}]}];
const tops = items.map(item => item.types.map(type => type.genres.map(genre => ({
name: type.name,
top_name: item.name,
...genre
})))).reduce(
(a, b) => a.concat(b), []
).reduce(
(a, b) => a.concat(b), []
).sort(
(a, b) => a.added_date > b.added_date ? -1 : a.added_date < b.added_date ? 1 : 0
).slice(0, 3)
console.log(tops)
在这些单独的循环中肯定存在一些效率低下的情况,排序可能是O(n * log(n))
,而即使是三部分的最大值也应该是O(n)
。但是,只有在您的应用程序出现瓶颈时,我才会担心这些问题。
答案 1 :(得分:2)
因此,如果我正确地理解了这个问题,则您希望按日期添加最新的3个值,并将其展平为特定格式。如果是这样,那么答案可能取决于您正在处理多少数据。一种选择是构建完全平面的数据数组,然后按日期排序。为此,我将使用数组展平实用程序功能(我已包含其中一个,但如果可以,请使用lodash)
例如:
const flatten = arr => arr.reduce((a, b) => a.concat(b), [])
const mapGenres = (topName, name, genres) => genres.map(genre => ({
name,
topName,
...genre
})
const result = flatten(items.map(({ name, types }) =>
flatten(types.map(type => mapGenres(name, type.name, type.genres)))
))
result.sort((a, b) => return b.added_date.localeCompare(a.added_date))
这未经测试,但应该很简单。拼合贴图的嵌套级别,在叶子上产生所需的输出。