我有一个包含故事的数组,每个故事都有一个" day",我希望能够在同一天"日"进入一个新的阵列。
stories = [
{
id: 1,
day: '18-02-2017',
user: 1,
story_data: //JSON containing a single story + other data
},
{
id: 2,
day: '18-02-2017',
user: 1,
story_data: //JSON containing a single story + other data
},
{
id: 3,
day: '17-02-2017',
user: 1,
story_data: //JSON containing a single story + other data
}
]
以下是我对输出数组的看法:
feed = [
{
day: '18-02-2017',
stories: [
//multiple JSON story items
]
},
{
day: '17-02-2017',
stories: [
//multiple JSON story items
]
}
]
我在NodeJS中使用Async库进行必要的FOR循环,因为我还需要在将数据添加到最终数组之前异步处理数据 - 我明白需要做什么才能使它已经完全超越了我的脑海,如何把它放到代码中。
答案 0 :(得分:2)
function groupByDay(arr) {
var hash = arr.reduce(function(h, s) { // h is the hash object, s is the current story
h[s.day] = h[s.day] || {'day': s.day, 'stories': []}; // if the hash doesn't have an entry for this story's day, then add it
h[s.day].stories.push(s); // add this story to the stories array of the object that acummulates the result for this day
return h;
}, {});
return Object.keys(hash).map(function(key) { // unwrap the objects from the hash object and return them as an array (the result)
return hash[key];
});
}
以下是Array.prototype.reduce
,Array.prototype.map
和Object.keys
的MDN文档。
答案 1 :(得分:2)
尝试运行此代码:
var jsonStories = {};
stories.forEach(function(story) {
if (!jsonStories[story['day']]) {
jsonStories[story['day']] = {
'day': story['day'],
'stories': []
};
}
jsonStories[story['day']]['stories'].push(story);
});
var storiesArr = [];
Object.keys(jsonStories).forEach(function(key) {
storiesArr.push(jsonStories[key]);
});
您将获得一个有序数组。 如果删除最后四行,也可以将其作为JSON数组。
答案 2 :(得分:1)
你可以在一个带有哈希表闭包的循环中完成它。
var stories = [{ id: 1, day: '18-02-2017', user: 1, story_data: '01' }, { id: 2, day: '18-02-2017', user: 1, story_data: '02' }, { id: 3, day: '17-02-2017', user: 1, story_data: '03' }],
result = stories.reduce(function (hash) {
return function (r, a) {
if (!hash[a.day]) {
hash[a.day] = { day: a.day, stories: [] };
r.push(hash[a.day]);
}
hash[a.day].stories.push(a);
return r;
};
}(Object.create(null)), []);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
答案 3 :(得分:1)
let day2story = {};
stories.forEach((story) => {
let curr = day2story[story.day] || [];
curr.push(story.story_data);
day2story[story.day] = curr;
});
let feed = [];
Object.keys(day2story).forEach((day) => feed.push({day: day, stories: day2story[day]}));
console.log(JSON.stringify(feed))
答案 4 :(得分:0)
您可以使用此ES6代码:
const result = Array.from(
stories.reduce(
(acc, {day, story_data}) => acc.set(day, (acc.get(day) || []).concat(story_data)),
new Map
),
([day, story_data]) => ({day, story_data})
);
const stories = [
{
id: 1,
day: '18-02-2017',
user: 1,
story_data: "story1"
},
{
id: 2,
day: '18-02-2017',
user: 1,
story_data: "story2"
},
{
id: 3,
day: '17-02-2017',
user: 1,
story_data: "story3"
}
];
const result = Array.from(
stories.reduce(
(acc, {day, story_data}) => acc.set(day, (acc.get(day) || []).concat(story_data)),
new Map
),
([day, story_data]) => ({day, story_data})
);
console.log(result);

.as-console-wrapper { max-height: 100% !important; top: 0; }

reduce
方法创建一个Map
,以日期为键,并将相应的故事数组作为值。因此,如果地图中尚未存在该关键字,则会获取一个空数组(|| []
),否则将获取其当前值,然后将新故事添加到该数组中。
reduce
返回的地图本身就是一个很好的结构,但是当你要求一个对象数组时,Array.from
被应用于该地图。这会产生一对数组(带有键/值条目的子数组),但Array.from
接受一个回调函数,使用该回调函数可以将该对转换为具有2个属性的对象。
此解决方案使用箭头函数,解构和Map
这些都是ES6的功能。