使用lodash按数组中的每个项目进行分组

时间:2015-07-16 08:59:55

标签: javascript data-structures mapping underscore.js lodash

我有一个来自API的这种数据结构,他们告诉我相应地对它们进行分组。

INPUT

{
    0: {
        id: 0,
        name: 'foo',
        categories: [
            'Category001',
            'Category002/sub-category001'
        ]
    },
    1: {
        id: 1,
        name: 'bar',
        categories: [
            'Category002/sub-category001'
        ]
    },
    2: {
        id: 2,
        name: 'bazz',
        categories: [
            'Category001',
            'Category002',
            'Category003'
        ]
    },
    3: {
        id: 3,
        name: 'rem',
        categories: [
            'Category001/sub-category002/nth-category008',
            'Category001/sub-category004',
            'Category003/sub-category001'
        ]
    }
}

渴望输出

{
    0: {
        "name": "Category001",
        "isCategory": true,
        "children": [
            {
                "id": 0,
                "name": "foo",
                "categoryPath": "Category001",
                "isCategory": false
            },
            {
                "id": 2,
                "name": "bazz",
                "categoryPath": "Category001",
                "isCategory": false
            },
            {
                "name": "sub-category004",
                "categoryPath": "Category001/sub-category004",
                "children": [
                    {
                        "id": 3,
                        "name": "rem",
                        "isCategory": false,

                    }
                ],
                "isCategory": true
            },
            {
                "name": "sub-category002",
                "categoryPath": "Category001/sub-category002",
                "children": [
                    {
                        "name": "sub-category008",
                        "categoryPath": "Category001/sub-category002/nth-category008",
                        "children": [
                            {
                                "id": 3,
                                "name": "rem",
                                "isCategory": false
                            }
                        ],
                        "isCategory": true
                    },

                ],
                "isCategory": true
            },
            {
                "name": "sub-category002",
                "categoryPath": "Category001/sub-category002",
                "isCategory": true
            }
        ],
        "categoryPath": ""
    },
    1: {
        "name": "Category002",
        "isCategory": true,
        "children": [
            {
                "id": 2,
                "name": "bazz",
                "categoryPath": "Category002",
                "isCategory": false
            },
            {
                "name": "sub-category001",
                "categoryPath": "Category002/sub-category001",
                "children": [
                    {
                        "id": 0,
                        "name": "foo",
                        "isCategory": false,

                    },
                    {
                        "id": 1,
                        "name": "bar",
                        "isCategory": false,

                    }
                ],
                "isCategory": true
            }
        ],
        "categoryPath": ""
    },
    2: {
        "name": "Category003",
        "isCategory": true,
        "children": [
            {
                "id": 2,
                "name": "bazz",
                "categoryPath": "Category002",
                "isCategory": false
            },
            {
                "name": "sub-category001",
                "categoryPath": "Category003/sub-category001",
                "children": [
                    {
                        "id": 0,
                        "name": "foo",
                        "isCategory": false,

                    }
                ],
                "isCategory": true
            }
        ],
        "categoryPath": ""
    }
}

问题

  1. 在lodash中有一种简单的方法吗?
  2. 一个简单的小组不会做,但LOL

    var groups = _.chain(items)
            .groupBy('categories')
            .pairs()
            .value();
    

1 个答案:

答案 0 :(得分:1)

除了lodash功能之外,这里无法避免自定义处理。以下是最多使用lodash的尝试:

var transformed = _(input)
    .transform(function (result, item) {
        _(item.categories)
            .map(function (categoryPath) {
                return categoryPath.split('/');
            })
            .each(function (categoryPathParts) {

                var dict = result;
                var par;

                var fullpath = _.reduce(categoryPathParts, function (path, category, i) {
                    path += (i > 0 ? '/' : '') + category;
                    if (!(par = _.find(dict, 'name', category))) {
                        dict.push(par = {
                            name: category,
                            categoryPath: (i > 0 ? path : ''),
                            isCategory: true,
                            children: []
                        });
                    }

                    dict = _.find(dict, 'name', category).children;

                    return path;
            }, "")

            par.children.push({
                id: item.id,
                name: item.name,
                isCategory: false,
                categoryPath: fullpath,
            });
        }).value();
    }, [])
    .transform(function (resObj, resCat, i) {
        resObj[i] = resCat;
    }, {});

var input = {
    0: {
        id: 0,
        name: 'foo',
        categories: [
            'Category001',
            'Category002/sub-category001']
    },
    1: {
        id: 1,
        name: 'bar',
        categories: [
            'Category002/sub-category001']
    },
    2: {
        id: 2,
        name: 'bazz',
        categories: [
            'Category001',
            'Category002',
            'Category003']
    },
    3: {
        id: 3,
        name: 'rem',
        categories: [
            'Category001/sub-category002/nth-category008',
            'Category001/sub-category004',
            'Category003/sub-category001']
    }
};

var transformed = _(input)
    .transform(function (result, item) {
        _(item.categories)
            .map(function (categoryPath) {
                return categoryPath.split('/');
            })
            .each(function (categoryPathParts) {

                var dict = result;
                var par;

                var fullpath = _.reduce(categoryPathParts, function (path, category, i) {
                    path += (i > 0 ? '/' : '') + category;
                    if (!(par = _.find(dict, 'name', category))) {
                        dict.push(par = {
                            name: category,
                            categoryPath: (i > 0 ? path : ''),
                            isCategory: true,
                            children: []
                        });
                    }

                    dict = _.find(dict, 'name', category).children;

                    return path;
            }, "")

            par.children.push({
                id: item.id,
                name: item.name,
                isCategory: false,
                categoryPath: fullpath,
            });
        }).value();
    }, [])
    .transform(function (resObj, resCat, i) {
        resObj[i] = resCat;
    }, {});

document.getElementById('resultArea').textContent = JSON.stringify(transformed, null, 2);
textarea {
  width: 100%;
}
<script src="http://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.0/lodash.min.js"></script>

<textarea id="resultArea" rows="111" ></textarea>