如何使用JavaScript根据多个条件汇总行?

How to summarize rows based on multiple conditions using JavaScript?

我有以下 table:

+-----------+-------------+------------+--------------+--------+-----+
| Tariff No | Description | Net Weight | Gross Weight | Amount | COO |
+-----------+-------------+------------+--------------+--------+-----+
|    900011 |         xyz |         40 |           50 |   1000 |  IT |
+-----------+-------------+------------+--------------+--------+-----+
|    900011 |         xyz |         40 |           50 |   1500 |  IT |
+-----------+-------------+------------+--------------+--------+-----+
|    400222 |         abc |         50 |           60 |   1000 |  CA |
+-----------+-------------+------------+--------------+--------+-----+
|    400222 |         def |         40 |           50 |   2000 |  DE |
+-----------+-------------+------------+--------------+--------+-----+

我需要总结这个 table 适当的“关税编号”和“COO”列,使得结果 table 如下:

+-----------+-----+------------+--------------+--------+
| Tariff No | COO | Net Weight | Gross Weight | Amount |
+-----------+-----+------------+--------------+--------+
|    900011 |  IT |         80 |          100 |   2500 |
+-----------+-----+------------+--------------+--------+
|    400222 |  CA |         50 |           60 |   1000 |
+-----------+-----+------------+--------------+--------+
|    400222 |  DE |         40 |           50 |   2000 |
+-----------+-----+------------+--------------+--------+

请注意,生成的 table 没有“说明”列。

如何使用 JavaScript 执行此操作?

这就是我使用 JavaScript 的方法。

  1. 首先我们需要将 table 建模为 JavaScript 中的数据:

    var table = [
        row(900011, "xyz", 40, 50, 1000, "IT"),
        row(900011, "xyz", 40, 50, 1500, "IT"),
        row(400222, "abc", 50, 60, 1000, "CA"),
        row(400222, "def", 40, 50, 2000, "DE")
    ];
    
    function row( tariffNo
                , description
                , netWeight
                , grossWeight
                , amount
                , coo) {
    
        return { tariffNo    : tariffNo
               , description : description
               , netWeight   : netWeight
               , grossWeight : grossWeight
               , amount      : amount
               , coo         : coo };
    }
    
  2. 接下来,我们创建一个 groupBy 函数,根据给定的 groupOf 函数将给定的 table 的行分类:

    function groupBy(groupOf, table) {
        var groups = {};
        var values = [];
    
        table.forEach(function (row) {
            var value = groupOf(row);
    
            if (groups.hasOwnProperty(value)) {
                var rows = groups[value];
            } else {
                var rows = groups[value] = [];
                values.push(value);
            }
    
            rows.push(row);
        });
    
        return values.map(getGroup);
    
        function getGroup(value) {
            return groups[value];
        }
    }
    
  3. 然后,我们根据“Tariff No”和“COO”将输入table分组如下:

    var groups = groupBy(groupOf, table);
    
    function groupOf(row) {
        return row.tariffNo + " " + row.coo;
    }
    
  4. 最后,我们使用下面的map/reduce操作来总结结果:

    var result = groups.map(summarize);
    
    function summarize(rows) {
        return rows.reduce(summary, { netWeight   : 0
                                    , grossWeight : 0
                                    , amount      : 0 });
    }
    
    function summary(sum, row) {
        return { tariffNo    : row.tariffNo
               , coo         : row.coo
               , netWeight   : sum.netWeight   + row.netWeight
               , grossWeight : sum.grossWeight + row.grossWeight
               , amount      : sum.amount      + row.amount };
    }
    

就是这样。把它们放在一起:

var table = [
    row(900011, "xyz", 40, 50, 1000, "IT"),
    row(900011, "xyz", 40, 50, 1500, "IT"),
    row(400222, "abc", 50, 60, 1000, "CA"),
    row(400222, "def", 40, 50, 2000, "DE")
];

var groups = groupBy(groupOf, table);

var result = groups.map(summarize);

alert(JSON.stringify(result, null, 4));

function row( tariffNo
            , description
            , netWeight
            , grossWeight
            , amount
            , coo) {

    return { tariffNo    : tariffNo
           , description : description
           , netWeight   : netWeight
           , grossWeight : grossWeight
           , amount      : amount
           , coo         : coo };
}

function groupBy(groupOf, table) {
    var groups = {};
    var values = [];

    table.forEach(function (row) {
        var value = groupOf(row);

        if (groups.hasOwnProperty(value)) {
            var rows = groups[value];
        } else {
            var rows = groups[value] = [];
            values.push(value);
        }

        rows.push(row);
    });

    return values.map(getGroup);

    function getGroup(value) {
        return groups[value];
    }
}

function groupOf(row) {
    return row.tariffNo + " " + row.coo;
}

function summarize(rows) {
    return rows.reduce(summary, { netWeight   : 0
                                , grossWeight : 0
                                , amount      : 0 });
}

function summary(sum, row) {
    return { tariffNo    : row.tariffNo
           , coo         : row.coo
           , netWeight   : sum.netWeight   + row.netWeight
           , grossWeight : sum.grossWeight + row.grossWeight
           , amount      : sum.amount      + row.amount };
}

希望对您有所帮助。