简体   繁体   English

将许多数组合并为一个数组(JavaScript)

[英]Merging many arrays into one array (JavaScript)

I'm trying to take an array of many arrays that contain many objects and manipulate it into an array of objects. 我正在尝试使用包含许多对象的许多数组的数组,并将其操作为对象数组。

So, let's say I have an array that looks like this: 所以,假设我有一个如下所示的数组:

[
    [
        {Name: 'Josh', email: 'josh@gmail.com', Points: 33},
        {Name: 'Doug', email: 'doug@gmail.com', Points: 12}
    ],
    [
        {Name: 'Josh', email: 'josh@gmail.com', Points: 11},
        {Name: 'Doug', email: 'doug@gmail.com', Points: 18}
    ],
    [
        {Name: 'Josh', email: 'josh@gmail.com', Points: 2},
        {Name: 'Doug', email: 'doug@gmail.com', Points: 27}
    ]
]​

The Desired outcome would be an array of objects that has a 'Points' property to hold an array of the points. 期望的结果将是一个对象数组,其具有“点”属性来保存点的数组。 So it would look like this: 所以它看起来像这样:

[
    {Name: 'Josh', email: 'josh@gmail.com', Points: [33, 11, 2]},
    {Name: 'Doug', email: 'doug@gmail.com', Points: [12, 18, 27]}
]

This problem seems simple, but I can't seem to figure out the best way of doing this. 这个问题看起来很简单,但我似乎无法弄清楚这样做的最佳方法。 If you want this data in a fiddle, I made this for you to play with: http://jsfiddle.net/Qhxzz/1/ 如果你想把这些数据放在一个小提琴里,我就让你玩这个: http//jsfiddle.net/Qhxzz/1/

Note that this depends on the input structure being static (no recursion here). 请注意,这取决于输入结构是静态的(这里没有递归)。 Assuming you're not using any libraries: 假设您没有使用任何库:

var result = [];

for (var i = 0; i < initial.length; i++) {
    var innerArray = initial[i];

    for (var j = 0; j < innerArray.length; j++) {
        var item = innerArray[j];

        var found = false;
        // search result for an object with a matching email prop
        for (var k = 0; k < result.length; k++) {
            if (result[k].email === item.email) {
                found = true;

                // add this Point to the Points array
                result[k].Points.push(item.Points);
            }
        }

        if (!found) {
            // convert Points to an array of Points
            item.Points = [item.Points];

            result.push(item);
        }
    }
}

http://jsfiddle.net/Qhxzz/2/ http://jsfiddle.net/Qhxzz/2/

Here's one way using .reduce() and .forEach() . 下面是使用的一种方式.reduce().forEach() (You'll need patches if you're supporting older browsers.) (如果您支持旧版浏览器,则需要修补程序。)

var consolidated = data.reduce(function(holder, arr) {
    arr.forEach(function(obj) {
        if (obj.email in holder.emails)
            holder.emails[obj.email].Points.push(obj.Points);
        else {
            holder.emails[obj.email] = obj;
            holder.result.push(obj);
            obj.Points = [obj.Points];
        }
    });
    return holder;
}, {emails:{},result:[]}).result;

And actually, we could flatten out the original Array using concat.apply() , and be left with one monolithic Array to iterate. 实际上,我们可以使用concat.apply()来展平原始数组,并留下一个单片数组进行迭代。

flat = [].concat.apply([], data);

This turns your data into this structure: 这会将您的data转换为此结构:

[{Name:"Josh", email:"josh@gmail.com", Points:33},
 {Name:"Doug", email:"doug@gmail.com", Points:12},
 {Name:"Josh", email:"josh@gmail.com", Points:11},
 {Name:"Doug", email:"doug@gmail.com", Points:18},
 {Name:"Josh", email:"josh@gmail.com", Points:2},
 {Name:"Doug", email:"doug@gmail.com", Points:27}]

And makes the consolidation a bit simpler by eliminating the need for the inner .forEach() . 并且通过消除对内部.forEach()的需要,使合并更简单一些。

var consolidated = flat.reduce(function(holder, obj) {
    if (obj.email in holder.emails)
        holder.emails[obj.email].Points.push(obj.Points);
    else {
        holder.emails[obj.email] = obj;
        holder.result.push(obj);
        obj.Points = [obj.Points];
    }
    return holder;
}, {emails:{}, result:[]}).result;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM