根据数组值将数组项合并到新数组中

时间:2017-02-18 22:05:50

标签: javascript arrays json async.js

我有一个包含故事的数组,每个故事都有一个" 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循环,因为我还需要在将数据添加到最终数组之前异步处理数据 - 我明白需要做什么才能使它已经完全超越了我的脑海,如何把它放到代码中。

5 个答案:

答案 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.reduceArray.prototype.mapObject.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的功能。