使用Javascript和Underscore.js

时间:2015-09-19 13:13:44

标签: javascript reactjs underscore.js

假设我有以下列表:

var products = [
    {"id": 6, "name": "product6", "category": "category2", "1": 54, "2": 37, "3": 64, "4":6, "5": 46, "6": 32, "7": 3},
    {"id": 5, "name": "product5", "category": "category2", "1": 54, "2": 37, "3": 64, "4":6, "5": 46, "6": 32, "7": 3},
    {"id": 7, "name": "product7", "category": "category1", "1": 54, "2": 37, "3": 64, "4":6, "5": 46, "6": 32, "7": 3},
    {"id": 1, "name": "product1", "category": "category1", "1": 54, "2": 37, "3": 64, "4":6, "5": 46, "6": 32, "7": 3},
    {"id": 3, "name": "product3", "category": "category2", "1": 54, "2": 37, "3": 64, "4":6, "5": 46, "6": 32, "7": 3},
    {"id": 8, "name": "product8", "category": "category1", "1": 54, "2": 37, "3": 64, "4":6, "5": 46, "6": 32, "7": 3},
    {"id": 2, "name": "product2", "category": "category3", "1": 54, "2": 37, "3": 64, "4":6, "5": 46, "6": 32, "7": 3},
    {"id": 4, "name": "product4", "category": "category1", "1": 54, "2": 37, "3": 64, "4":6, "5": 46, "6": 32, "7": 3}
] 

我怎样才能使用javascript和"理想情况下使用undercore.js groupBy将其变成这样的东西? (或考虑下面的表格布局,您是否知道如何在这里包括几个月?)。正如我在下面看到的那样嵌套 结构会让我几乎"那里。

var hierarchicalList = [
    { 
        "id": -1, // something unique I guess?
        "name": "category1", 
        "1": 216, // aggregate number of sales per week for all children
        "2": 148, 
        "3": 256, 
        "4": 24, 
        "5": 184, 
        "6": 128, 
        "7": 12,
        "children": [
            {
                "id": 7, 
                "name": "product7", 
                "1": 54, 
                "2": 37, 
                "3": 64, 
                "4":6, 
                "5": 46, 
                "6": 32, 
                "7": 3
            }
            {
                "id": 1, 
                "name": "product1", 
                "1": 54, 
                "2": 37, 
                "3": 64, 
                "4":6, 
                "5": 46, 
                "6": 32, 
                "7": 3
            }
        ]
    }, 
    { 
        "id": -2, 
        "name": "category2",  
        "1": 162, 
        "2": 111, 
        ...
        "7": 9,
        "children": [
            // product6, 5, 3
        ]
    }
]

我将把它用于"行分组"在表格中的产品类别中,我希望将我的数据结构插入反应网格组件,如Griddle 总而言之,就我而言,我将如何:

  • 从下划线groupBy类别结果中获取每周每类别的汇总销售额?

https://jsfiddle.net/zt62a3Lc/

2 个答案:

答案 0 :(得分:0)

好。这是一个潜在的解决方案。它可能不会使用_.groupBy,但IMO如果你强迫自己走上这条道路,你可能会试图用双手绑在背后解决问题。

var categoryGraft = {};
products.forEach(function (product) {
    var key = product.category;
    if (typeof categoryGraft[key] === 'undefined') {
        categoryGraft[key] = {
            "1": 0, "2": 0, "3": 0, "4": 0, "5": 0, "6": 0, "7": 0,
            "name": key,
            "children": []
        };
    }

    categoryGraft[key]["1"] += product["1"];
    categoryGraft[key]["2"] += product["2"];
    categoryGraft[key]["3"] += product["3"];
    categoryGraft[key]["4"] += product["4"];
    categoryGraft[key]["5"] += product["5"];
    categoryGraft[key]["6"] += product["6"];
    categoryGraft[key]["7"] += product["7"];

    // delete from original or clone...
    delete product.category;
    categoryGraft[key].children.push(product);
});

var hierarchicalList = [];
var key, category;
for (key in categoryGraft) {
    category = categoryGraft[key];
    hierarchicalList.push(category);
}

答案 1 :(得分:0)

这是我使用_.chain()

的解决方案

它不限于1 to 7,可以使用任意数量的数字属性。此外,它是一个功能解决方案,不会改变任何变量。

    var products = [
        {"id": 6, "name": "product6", "category": "category2", "1": 54, "2": 37, "3": 64, "4":6, "5": 46, "6": 32, "7": 3},
        {"id": 5, "name": "product5", "category": "category2", "1": 54, "2": 37, "3": 64, "4":6, "5": 46, "6": 32, "7": 3},
        {"id": 7, "name": "product7", "category": "category1", "1": 54, "2": 37, "3": 64, "4":6, "5": 46, "6": 32, "7": 3},
        {"id": 1, "name": "product1", "category": "category1", "1": 54, "2": 37, "3": 64, "4":6, "5": 46, "6": 32, "7": 3},
        {"id": 3, "name": "product3", "category": "category2", "1": 54, "2": 37, "3": 64, "4":6, "5": 46, "6": 32, "7": 3},
        {"id": 8, "name": "product8", "category": "category1", "1": 54, "2": 37, "3": 64, "4":6, "5": 46, "6": 32, "7": 3},
        {"id": 2, "name": "product2", "category": "category3", "1": 54, "2": 37, "3": 64, "4":6, "5": 46, "6": 32, "7": 3},
        {"id": 4, "name": "product4", "category": "category1", "1": 54, "2": 37, "3": 64, "4":6, "5": 46, "6": 32, "7": 3}
    ] 

    // null coalescing helper
    var coal = (a, b) => a != null ? a : b

    _.chain(products)
    // make an object: {category1: [...], category2: [...], ...}
    .groupBy(c => c.category)
    .mapObject((val, key) =>
        _.chain(val)
        .reduce(
            ((a, b) =>
                _.chain(_.chain(a).keys().union(_.keys(b)).value())
                .filter(k => !_(['name', 'id']).contains(k))
                .map(k =>
                    [k, !isNaN(parseInt(k)) ? coal(a[k], 0) + coal(b[k], 0) : coal(a[k], b[k])]
                )
                .concat([["children", _(a.children).concat(b)]])
                .object()
                .value()

            ), {children: []}
        )
        .value()
    )
    // convert the object into a list of pairs [["category1", {...}], ["category2", {...}], ...]
    .pairs()
    .map((d, i) => 
        // d is a pair: ["category1", {...}]
        _.extend(d[1], {name: d[0], id: (i+1) * -1}) // make the id
    )
    .value()