【问题标题】:Convert object to array and map name as key and children将对象转换为数组并将映射名称作为键和子项
【发布时间】:2015-07-21 09:54:23
【问题描述】:

我有这个数据集

var items = {
    1: {
        id: 1,
        name: 'foo',
        date: {
            MMM  : 'february',
            yyyy : '2014',
            S    : '14th'
        }
    },
    2: {
        id: 2,
        name: 'bar',
        date: {
            MMM  : 'february',
            yyyy : '2014',
            S    : '7th'
        }
    },
    3: {
        id: 3,
        name: 'bazz',
        date: {
            MMM  : 'august',
            yyyy : '2015',
            S    : '21st'
        }
    },
    4: {
        id: 4,
        name: 'sup',
        date: {
            MMM  : 'may',
            yyyy : '2015',
            S    : '8th'
        }
    },
    5: {
        id: 6,
        name: 'awe',
        date: {
            MMM  : 'february',
            yyyy : '2014',
            S    : '1st'
        }
    }

};

我使用 lodash 和这个自定义函数对它们进行了分组:

_.groupByMulti = function(obj, values, context) {
    if (!values.length) {
        return obj;
    }
    var byFirst = _.chain(obj)
    .groupBy(values[0], context)
    .value();

    var rest = values.slice(1);

    for (var prop in byFirst) {
        if (prop) {
            byFirst[prop] = _.groupByMulti(byFirst[prop], rest, context);
        }
    }

    return byFirst;
}

所以_.groupByMulti(items, ['date.yyyy', 'date.MMM', 'date.S']); 会重新运行:

{
    "2014": {
        "february": {
            "14th": [
                {
                    "id": 1,
                    "name": "foo",
                    "date": {
                        "MMM": "february",
                        "yyyy": "2014",
                        "S": "14th"
                    }
                }
            ],
            "7th": [
                {
                    "id": 2,
                    "name": "bar",
                    "date": {
                        "MMM": "february",
                        "yyyy": "2014",
                        "S": "7th"
                    }
                }
            ],
            "1st": [
                {
                    "id": 6,
                    "name": "awe",
                    "date": {
                        "MMM": "february",
                        "yyyy": "2014",
                        "S": "1st"
                    }
                }
            ]
        }
    },
    "2015": {
        "august": {
            "21st": [
                {
                    "id": 3,
                    "name": "bazz",
                    "date": {
                        "MMM": "august",
                        "yyyy": "2015",
                        "S": "21st"
                    }
                }
            ]
        },
        "may": {
            "8th": [
                {
                    "id": 4,
                    "name": "sup",
                    "date": {
                        "MMM": "may",
                        "yyyy": "2015",
                        "S": "8th"
                    }
                }
            ]
        }
    }
}

现在我如何扩展我的 lodash 函数,以便它将对象转换为数组,并让它们像这样:

[
    {
       key: '2015',
       children: [
           {
              key: 'february',
              children: [...]
           }
       ]
    }
]

【问题讨论】:

    标签: javascript sorting lodash


    【解决方案1】:

    鉴于您目前拥有:

    var out = _.groupByMulti(items, ['date.yyyy', 'date.MMM', 'date.S']);
    

    返回一个对象。要将其包装到数组中,这可能会奏效:

    _.map(_.keys(out), function(year){
    
        return {
            key: year,
            children: _.map(_.keys(out[year]),function(month){
                return {
                    key: month,
                    children: out[year][month]
                }
            })
        }
    });
    

    【讨论】:

    • 问题在于,它不是那么灵活,如果我 groupMulti 使用不同数量的道具会怎样。
    • 听起来更像是您在寻找一个通用解决方案,它不仅可以解决您的示例场景,还可以解决它的其他变体。顺便说一句,好问题。
    • 啊,是的,一个更通用的解决方案。 .感谢您提供一个想法顺便说一句
    【解决方案2】:

    按照@Tao P. R. 的回答,我能够像这样扩展groupByMulti 函数:

    _.groupByMulti = function(obj, values, context) {
        if (!values.length) {
            return obj;
        }
        var byFirst = _.chain(obj)
            .groupBy(values[0], context)
            .value();
    
        var rest = values.slice(1);
    
        for (var prop in byFirst) {
            if (prop) {
                byFirst[prop] = _.groupByMulti(byFirst[prop], rest, context);
            }
        }
    
        byFirst = _.map(_.keys(byFirst), function(propName) {
            return {
                name: propName,
                children: byFirst[propName]
            }
        });
    
        return byFirst;
    }
    
    return _;
    

    【讨论】:

      猜你喜欢
      • 2019-05-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-18
      • 1970-01-01
      相关资源
      最近更新 更多