我们在写js的时候经常会遇到分组的问题,比如把一些散列数据组织成树形结构,我们会根据数据的归属关系,用递归的方式组织成带层级关系的数据。
不过有时候我们的数据可能没那么复杂,可能就是根据某一个字段进行分组,这时用递归就不太合适了。
oneGroup.js:
var arr = [{
"id": "1001",
"name": "同学1",
"value": "jack"
},
{
"id": "1001",
"name": "同学1",
"value": "tom"
},
{
"id": "1002",
"name": "同学2",
"value": "mike"
},
{
"id": "1002",
"name": "同学2",
"value": "lily"
},
{
"id": "1002",
"name": "同学2",
"value": "joe"
},
{
"id": "1003",
"name": "同学3",
"value": "harry"
}
];
function handleGroup(arr) {
let obj = {};
let groups = [];
arr.forEach(item => {
if (!obj[item.id]) { //根据id分组
groups.push({
groupName: item.id,
items: [item]
});
obj[item.id] = item;
} else {
groups.find(v => {//选择符合条件的第一个元素
if (v.groupName === item.id) {
v.items.push(item);
}
});
}
});
return groups;
}
console.log(handleGroup(arr));
这个数据结构还是比较容易的,只是一个字段一次分组。下面这个是两个字段两次分组。
twoGroup.ts:
var arr = [{
name: 'background-color',
value: '#ff0000',
group: "外观",
subGroup: "背景"
},
{
name: 'background-opacity',
value: '0.2',
group: "外观",
subGroup: "背景"
},
{
name: 'border-color',
value: '#ffff00',
group: "外观",
subGroup: "边框"
},
{
name: 'border-width',
value: '2px',
group: "外观",
subGroup: "边框"
},
{
name: 'border-style',
value: 'solid',
group: "外观",
subGroup: "边框"
},
{
name: 'height',
value: '500px',
group: "大小",
subGroup: "宽高"
},
{
name: 'width',
value: '500px',
group: "大小",
subGroup: "宽高"
},
{
name: 'color',
value: '#fff',
group: "大小",
subGroup: ""
}
];
class GroupItems{
//groupName:string;
items = [];
subGroups:Items[] = [];
constructor(public groupName:string){
// this.groupName = groupName;
}
}
class Items {
items = [];
//subgroupName:string;
constructor(public subgroupName:string){
//this.subgroupName = subgroupName;
}
}
function handleGroup(arr) {
let groups = [];
for(const v of arr){
if(v.group) {
let group = groups.find(o=>o.groupName === v.group);
if(!group) {
group = new GroupItems(v.group);
groups.push(group);
}
if(v.subGroup){
let subgroup = group.subGroups.find(s=>s.subgroupName === v.subGroup);
if(!subgroup){
subgroup = new Items(v.subGroup);
group.subGroups.push(subgroup);
}
subgroup.items.push(v);
} else {
group.items.push(v);//无subgroup的数据
}
}
}
return groups;
}
console.log(handleGroup(arr));
这个对数据进行了二次分组,第一次是大分组,第二次是小分组。这里借助了class类,让代码变得更加优雅。
大家注意一下哦,es6和ts在某些写法上有一些混淆,比如constructor构造器的写法。
ts中可以在构造器的形参中直接声明变量:
constructor(public subgroupName:string){
}
其结果就等同于在外面声明变量并初始化:
subgroupName;
constructor(subgroupName){
this.subgroupName = subgroupName;
}
这种写法我们在angular中经常会遇到,比如service在使用时必须先初始化,都是直接在构造器的形参直接声明的。