我正在尝试确定最佳数据类型,以将对象数组排序到属性定义的组中。我有一个对象数组,如下所示:
var people = [
{
name: 'Pete',
gender: 'Male',
age: 22
},
{
name: 'Samantha',
gender: 'Female',
age: 20
},
{
name: 'Frank',
gender: 'Male',
age: 22
},
{
name: 'Gary',
gender: 'Male',
age: 21
},
{
name: 'Maria',
gender: 'Female',
age: 20
},
{
name: 'Hannah',
gender: 'Female',
age: 21
},
{
name: 'Pete',
gender: 'Male',
age: 20
}
];
我需要将这些对象分组到任意定义的组中。 E.g:
gender
age
(这可以由服务器定义,如果我们愿意,可以更改为包含第三组。)
然后给我(视觉上):
Male:
21:
Gary
22:
Pete
Frank
Female
20:
Samantha
Maria
21:
Hannah
我认为适当的数据类型将是对象的对象。即:
{
Male: {
21: {
[
{
name: 'Gary',
gender: 'Male',
age: 21
}
]
},
22: {
[
{
name: 'Pete',
gender: 'Male',
age: 22
},
{
name: 'Frank',
gender: 'Male',
age: 22
}
]
}
},
Female: {
20: {
[
{
name: 'Samantha',
gender: 'Female',
age: 20
},
{
name: 'Maria',
gender: 'Female',
age: 20
}
]
},
21: {
[
{
name: 'Hannah',
gender: 'Female',
age: 21
}
]
}
}
}
但是,对于我的生活,我无法解决这些问题,将这些对象分类为代表上述数据的数据类型。
underscore.js
中有一个名为_.groupBy(arr, callback)
的实用工具,我可以按如下方式使用:
_.groupBy(people, function (person) {
var props = ['gender', 'age'], // server-defined
prop = [];
for (var i = 0, length = props.length; i < length; i++) {
prop.push(person[props[i]]);
}
return prop.join('|');
});
这给了我一个1深度的对象,我可以使用for...in
循环遍历键,然后循环构建上面的对象,但这是我坚持的代码。
返回的对象是:
{
"Male|22": [
{
"name": "Pete",
"gender": "Male",
"age": 22
},
{
"name": "Frank",
"gender": "Male",
"age": 22
}
],
"Female|20": [
{
"name": "Samantha",
"gender": "Female",
"age": 20
},
{
"name": "Maria",
"gender": "Female",
"age": 20
}
],
"Male|21": [
{
"name": "Gary",
"gender": "Male",
"age": 21
}
],
"Female|21": [
{
"name": "Hannah",
"gender": "Female",
"age": 21
}
],
"Male|20": [
{
"name": "Pete",
"gender": "Male",
"age": 20
}
]
}
我正在考虑循环遍历对象中的每个键,在管道(|
)处拆分并使用递归来构造包含数据组/数组的对象的新对象。
这是实现这一目标的可怕方式,但我不知道如何做到这一点。
我错过了更好的方法吗?
答案 0 :(得分:2)
也许这会对你有所帮助。它使用具有对象属性的数组,结果按属性的内容进行分组。
forEach
循环遍历数据。 reduce
循环用于为每个给定组生成分组属性,如果它是最后一个,则返回一个数组(如果尚未存在)。
最后一步是将其中一个人的值推送到数组。
var people = [{ name: 'Pete', gender: 'Male', age: 22 }, { name: 'Samantha', gender: 'Female', age: 20 }, { name: 'Frank', gender: 'Male', age: 22 }, { name: 'Gary', gender: 'Male', age: 21 }, { name: 'Maria', gender: 'Female', age: 20 }, { name: 'Hannah', gender: 'Female', age: 21 }, { name: 'Pete', gender: 'Male', age: 20 }],
groups = ['gender', 'age'],
grouped = {};
people.forEach(function (a) {
groups.reduce(function (o, g, i) { // take existing object,
o[a[g]] = o[a[g]] || (i + 1 === groups.length ? [] : {}); // or generate new obj, or
return o[a[g]]; // at last, then an array
}, grouped).push(a);
});
document.write('<pre>' + JSON.stringify(grouped, 0, 4) + '</pre>');
&#13;
答案 1 :(得分:1)
我不同意你的预期输出。我认为你应该只有一个具有Male
和Female
数组属性的对象,并使用此代码填充数组:
var obj = people.reduce(function (p, c, i) {
p[c.gender].push(c);
return p;
}, { Male: [], Female: [] });
如果您想过滤那些数组,可以编写如下函数:
function getMaleByAge(obj, age) {
return obj.Male.filter(function (el) {
return el.age === age;
})
}
getMaleByAge(obj, 21); // { name: "Gary", gender: "Male", age: 21 }
答案 2 :(得分:1)
使用_.groupBy
&amp; _.map
var output _.map(_.groupBy(people,'gender'),function(obj,key){
var temp = {};
temp[key] = _.groupBy(obj,'age')
return temp;
});
console.log(JSON.stringify(output,null,' '))
将提供以下输出
[{
"Male": {
"20": [
{
"name": "Pete",
"gender": "Male",
"age": 20
}
],
"21": [
{
"name": "Gary",
"gender": "Male",
"age": 21
}
],
"22": [
{
"name": "Pete",
"gender": "Male",
"age": 22
},
{
"name": "Frank",
"gender": "Male",
"age": 22
}
]
}
},
{
"Female": {
"20": [
{
"name": "Samantha",
"gender": "Female",
"age": 20
},
{
"name": "Maria",
"gender": "Female",
"age": 20
}
],
"21": [
{
"name": "Hannah",
"gender": "Female",
"age": 21
}
]
}
}
]
答案 3 :(得分:0)
我真的不明白为什么人们总是使用框架来做这类事情。 香草是faster,这不是很难编码......
var people = [ { name: 'Pete', gender: 'Male', age: 22 }, { name: 'Samantha', gender: 'Female', age: 20 }, { name: 'Frank', gender: 'Male', age: 22 }, { name: 'Gary', gender: 'Male', age: 21 }, { name: 'Maria', gender: 'Female', age: 20 }, { name: 'Hannah', gender: 'Female', age: 21 }, { name: 'Pete', gender: 'Male', age: 20 }];
var grouped = {}; // final object
for (var i=0,len=people.length,p;i<len;i++) { // faster than .forEach
p = people[i];
if (grouped[p.gender] === undefined) // twice faster then hasOwnProperty
grouped[p.gender] = {};
if (grouped[p.gender][p.age] === undefined)
grouped[p.gender][p.age] = [];
grouped[p.gender][p.age].push(p); // your groupby is HERE xD
}
document.getElementById('grouped').innerHTML = JSON.stringify(grouped, null, 2)
&#13;
<pre id="grouped"></pre>
&#13;