js数据分组

我们在写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在使用时必须先初始化,都是直接在构造器的形参直接声明的。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容