我想总结一个对象数组,并在另一个对象数组中返回对象出现次数。这样做的最佳方式是什么?
来自此
var arrayOfSongs = [
{"title":"Blue","duration":161.71,"audioUrl":"/assets/music/blue","playing":false,"playedAt":"2016-12-21T22:58:55.203Z"},
{"title":"Blue","duration":161.71,"audioUrl":"/assets/music/blue","playing":false,"playedAt":"2016-12-21T22:58:55.203Z"},
{"title":"Blue","duration":161.71,"audioUrl":"/assets/music/blue","playing":false,"playedAt":"2016-12-21T22:58:55.203Z"},
{"title":"Green","duration":161.71,"audioUrl":"/assets/music/blue","playing":false,"playedAt":"2016-12-21T22:58:55.203Z"}
];
到此
var newArrayOfSongs = [
{"title": "Blue", "playCount": 3 },
{"title": "Green", "playCount": 1}
]
我试过
arrayOfSongs.reduce(function(acc, cv) {
acc[cv.title] = (acc[cv.title] || 0) + 1;
return acc;
}, {});
}
但它返回一个对象:
{ "Blue": 3, "Green": 1};
答案 0 :(得分:1)
您应该将初始参数作为数组传递给reduce
函数而不是现有值的对象和过滤器数组,如下所示,
工作代码:
var arrayOfSongs = [
{"title":"Blue","duration":161.71,"audioUrl":"/assets/music/blue","playing":false,"playedAt":"2016-12-21T22:58:55.203Z"},
{"title":"Blue","duration":161.71,"audioUrl":"/assets/music/blue","playing":false,"playedAt":"2016-12-21T22:58:55.203Z"},
{"title":"Blue","duration":161.71,"audioUrl":"/assets/music/blue","playing":false,"playedAt":"2016-12-21T22:58:55.203Z"},
{"title":"Green","duration":161.71,"audioUrl":"/assets/music/blue","playing":false,"playedAt":"2016-12-21T22:58:55.203Z"}
];
var newArrayOfSongs = arrayOfSongs.reduce(function(acc, cv) {
var arr = acc.filter(function(obj) {
return obj.title === cv.title;
});
if(arr.length === 0) {
acc.push({title: cv.title, playCount: 1});
} else {
arr[0].playCount += 1;
}
return acc;
}, []);
console.log(newArrayOfSongs);
答案 1 :(得分:1)
要建立你已经完成的工作,下一步是将对象“转换”为数组
NULL
答案 2 :(得分:1)
我建议分两个阶段进行。首先,按标题对数组进行分块,然后将块映射到您想要的输出中。这将真正帮助您在未来的变化。一次性完成这一过程非常复杂,并且将增加将来搞乱的可能性。
var arrayOfSongs = [
{"title":"Blue","duration":161.71,"audioUrl":"/assets/music/blue","playing":false,"playedAt":"2016-12-21T22:58:55.203Z"},
{"title":"Blue","duration":161.71,"audioUrl":"/assets/music/blue","playing":false,"playedAt":"2016-12-21T22:58:55.203Z"},
{"title":"Blue","duration":161.71,"audioUrl":"/assets/music/blue","playing":false,"playedAt":"2016-12-21T22:58:55.203Z"},
{"title":"Green","duration":161.71,"audioUrl":"/assets/music/blue","playing":false,"playedAt":"2016-12-21T22:58:55.203Z"}
];
function chunkByAttribute(arr, attr) {
return arr.reduce(function(acc, e) {
acc[e[attr]] = acc[e[attr]] || [];
acc[e[attr]].push(e);
return acc;
}, {});
}
var songsByTitle = chunkByAttribute(arrayOfSongs, 'title');
var formattedOutput = Object.keys(songsByTitle).map(function (title) {
return {
title: title,
playCount: songsByTitle[title].length
};
});
在那里,现在一切都根据它的作用命名,一切都只做一件事,并且更容易理解。
答案 3 :(得分:0)
https://jsfiddle.net/93e35wcq/
我使用set对象来获取唯一的曲目标题,然后使用Array.map拼接它们并返回包含曲目标题内的播放计数的歌曲对象。
数据:
var arrayOfSongs = [{
"title": "Blue",
"duration": 161.71,
"audioUrl": "/assets/music/blue",
"playing": false,
"playedAt": "2016-12-21T22:58:55.203Z"
}, {
"title": "Blue",
"duration": 161.71,
"audioUrl": "/assets/music/blue",
"playing": false,
"playedAt": "2016-12-21T22:58:55.203Z"
}, {
"title": "Blue",
"duration": 161.71,
"audioUrl": "/assets/music/blue",
"playing": false,
"playedAt": "2016-12-21T22:58:55.203Z"
}, {
"title": "Green",
"duration": 161.71,
"audioUrl": "/assets/music/blue",
"playing": false,
"playedAt": "2016-12-21T22:58:55.203Z"
}];
功能:
function getPlayCount(arrayOfSongs) {
let songObj = {};
let SongSet = new Set();
arrayOfSongs.map(obj => (SongSet.has(obj.title)) ? true : SongSet.add(obj.title));
for (let songTitle of SongSet.values()) {
songObj[songTitle] = {
playCount: 0
};
arrayOfSongs.map(obj => (obj.title === songTitle) ? songObj[songTitle].playCount++ : false)
}
return songObj;
}
console.log(getPlayCount(arrayOfSongs));
这并不是你想要格式化的东西,但是如果你嫁给了它,这就行了:
function getPlayCount(arrayOfSongs) {
let songObj = {};
let SongSet = new Set();
arrayOfSongs.map(obj => (SongSet.has(obj.title)) ? true : SongSet.add(obj.title));
for (let songTitle of SongSet.values()) {
songObj[songTitle] = 0;
arrayOfSongs.map(obj => (obj.title === songTitle) ? songObj[songTitle]++ : false)
}
return songObj;
}
console.log(getPlayCount(arrayOfSongs));