2015-06-18 60 views
1

我有一个按ID分组的集合。每个id都包含对象数组。我想遍历它并创建一个目标集合,它将按照示例中所示的“Id”列进行分组。我不会使用下划线js。我必须使用javascript reduce方法来实现这一点。Groupby不使用下划线js

var targetCollection = [{ 
 
    123456: [ 
 
     { "Id": "1", "name": "xxx", "age": "22" }, 
 
     { "Id": "1", "name": "yyy", "age": "15" }, 
 
     { "Id": "5", "name": "zzz", "age": "59" } 
 
    ], 
 
    789456: [ 
 
     { "Id": "1", "name": "xxx", "age": "22" }, 
 
     { "Id": "1", "name": "yyy", "age": "15" }, 
 
     { "Id": "5", "name": "zzz", "age": "59" } 
 
    ] 
 
}] 
 

 
var targetOutput = [{ 
 
    123456: { 
 
     1: [{ "Id": "1", "name": "xxx", "age": "22" }, { "Id": "1", "name": "yyy", "age": "15" }], 
 
     5: [{ "Id": "5", "name": "zzz", "age": "59" }] 
 
    }, 
 
    789456: { 
 
     1: [{ "Id": "1", "name": "xxx", "age": "22" }, { "Id": "1", "name": "yyy", "age": "15" }], 
 
     5: [{ "Id": "5", "name": "zzz", "age": "59" }] 
 
    } 
 
}]

Code Snippet I have tried which didn't work 
 

 
var newArray = []; 
 
$.each(targetCollection, function (key, value) { 
 
    var newTarget = $(this); 
 
    var targetCollectionNew = newTarget.reduce(function (result, current) { 
 
     result[current.ParentAreaID] = result[current.ParentAreaID] || []; 
 
     result[current.ParentAreaID].push(current); 
 
     return result; 
 
    }, {}); 
 

 
    newArray.push(targetCollectionNew); 
 
}); 
 

 
console.log('newArray', newArray);

我试图与阵列减少方法,它没有工作。请帮帮我。

+0

的解决方案是很容易的,但你尝试过这么远吗?哪些代码不起作用? –

+0

如果你能让我知道解决方案,那将是非常棒的。我已经尝试了很多东西,现在它不会退缩到你所要求的位置。 –

+0

发布最新代码不应太难。否则,你只需发布一个问题集。 –

回答

3

你原来的尝试的问题是你需要有两个循环,因为在第一个newValue是一个对象不是数组,所以没有reduce方法就可以了。

更简单的解决方案是使用地图(您可以使用forEach$.each)并减少第二个循环(我使用简单的for-in)。

事情是这样的:

var targetCollection = [{ 
 
    123456: [ 
 
     { "Id": "1", "name": "xxx", "age": "22" }, 
 
     { "Id": "1", "name": "yyy", "age": "15" }, 
 
     { "Id": "5", "name": "zzz", "age": "59" } 
 
    ], 
 
    789456: [ 
 
     { "Id": "1", "name": "xxx", "age": "22" }, 
 
     { "Id": "1", "name": "yyy", "age": "15" }, 
 
     { "Id": "5", "name": "zzz", "age": "59" } 
 
    ] 
 
}]; 
 

 
var result = targetCollection.map(function(obj) { 
 
    for (var key in obj) { 
 
     obj[key] = obj[key].reduce(function(prev, curr) { 
 
      if (!prev[curr.Id]) prev[curr.Id] = []; 
 
      prev[curr.Id].push(curr); 
 
      return prev; 
 
     }, {}); 
 
    } 
 
    return obj; 
 
}); 
 

 
document.write('<pre>' + JSON.stringify(result, null, 4) + '</pre>');

+0

嘿!你知道你是冠军!!!这工作完美,并感谢解释这个错误。这真的有帮助。 –

+1

这将修改原始对象。看到我的答案为什么。 –

+0

@JasonCust是的我知道,但我觉得这不是问题(也许这是需要重新构建的服务器的响应)。在大多数情况下,我希望对象在包装器数组转换后仍然是引用。顺便说一句,你的解决方案也是通过引用传递对象。 – dfsq

2

你应该比较当前的对象,targetCollection,和您所需的输出对象,targetOutput,谋划变革,你将需要:

targetCollection: Array --> Object --> Array --> Object 
targetObject: Array --> Object --> Object --> Array --> Object 

您可以看到外部数组将是1:1映射,所以t这里没有必要在这里减少。

下一级是对象,但它又是1:1映射。但是,因为JavaScript通过引用传递对象,您将需要创建一个新对象以避免修改原始对象。既然我们是从另一个对象创建一个对象,我们可以利用Object.keys的强大功能来创建一个数组,然后使用Array.reduce从这些关键字创建一个对象。

第三个层次是我们第一次遇到结构从数组到实体的真实转换的地方。再次,我们可以使用Array.reduce来帮助这一步。

所以从这个攻击计划你可以看到流程应该是map --> reduce --> reduce

var targetCollection = [{ 
 
    123456: [{ 
 
    "Id": "1", 
 
    "name": "xxx", 
 
    "age": "22" 
 
    }, { 
 
    "Id": "1", 
 
    "name": "yyy", 
 
    "age": "15" 
 
    }, { 
 
    "Id": "5", 
 
    "name": "zzz", 
 
    "age": "59" 
 
    }], 
 
    789456: [{ 
 
    "Id": "1", 
 
    "name": "xxx", 
 
    "age": "22" 
 
    }, { 
 
    "Id": "1", 
 
    "name": "yyy", 
 
    "age": "15" 
 
    }, { 
 
    "Id": "5", 
 
    "name": "zzz", 
 
    "age": "59" 
 
    }] 
 
}]; 
 

 
// 1:1 mapping 
 
var targetOutput = targetCollection.map(function(obj) { 
 
    // 1:1 mapping but we need to create a new object to 
 
    // avoid modifying the original object 
 
    // Object.keys returns an array of keys (that are enumerable) 
 
    // and then reduce creates the new object 
 
    return Object.keys(obj).reduce(function(newObj, key) { 
 
    // The desired transformation takes place here 
 
    newObj[key] = obj[key].reduce(function(idObj, el) { 
 
     idObj[el.Id] = idObj[el.Id] || []; 
 
     // This will pass by reference the internal objects 
 
     // so you could use the prior technique to create 
 
     // a new object to avoid downstream modification 
 
     idObj[el.Id].push(el); 
 

 
     return idObj; 
 
    }, {}); 
 

 
    return newObj; 
 
    }, {}); 
 
}); 
 

 
document.write('<h3>targetCollection</h3><pre>' + JSON.stringify(targetCollection, null, 4) + '</pre>'); 
 
document.write('<h3>targetOutput</h3><pre>' + JSON.stringify(targetOutput, null, 4) + '</pre>');