根据数组值将数组项合并到新数组中
Merge array items into new array based on array value
我有一个包含故事的数组,每个故事也有一个 "day",我希望能够将同一个 "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 循环,因为我还需要在将数据添加到这个最终数组之前异步处理数据 - 我明白制作新数组需要做些什么我一直在思考如何将其放入代码中。
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
and Object.keys
的 MDN 文档。
您可以在单个循环中完成此操作,并在散列上使用闭包 table。
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; }
试试运行这个代码:
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 数组获取。
你可以使用这个 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
应用于该地图。这会产生一个对数组(sub-arrays 带有键/值条目),但是 Array.from
接受一个回调函数,通过该函数可以将这个对转换为具有 2 个属性的对象。
这个解决方案使用箭头函数、解构和 Map
这些都是 ES6 的特性。
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))
我有一个包含故事的数组,每个故事也有一个 "day",我希望能够将同一个 "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 循环,因为我还需要在将数据添加到这个最终数组之前异步处理数据 - 我明白制作新数组需要做些什么我一直在思考如何将其放入代码中。
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
and Object.keys
的 MDN 文档。
您可以在单个循环中完成此操作,并在散列上使用闭包 table。
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; }
试试运行这个代码:
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 数组获取。
你可以使用这个 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
应用于该地图。这会产生一个对数组(sub-arrays 带有键/值条目),但是 Array.from
接受一个回调函数,通过该函数可以将这个对转换为具有 2 个属性的对象。
这个解决方案使用箭头函数、解构和 Map
这些都是 ES6 的特性。
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))