使用 lodash 转换集合

Transforming collection using lodash

本文关键字:集合 转换 lodash 使用      更新时间:2023-09-26

我有一个查询,它给了我Json数据;例如,我有以下Json

{
"salesInvoices":
    [
    {
        "id": "1",
        "salesInvoiceLines":
        [
            {
                "ItemCode": "Apple",
                "UnitCode": "piece",
                "Quantity": "10"
            },
            {
                "ItemCode": "Orange",
                "UnitCode": "box",
                "Quantity": "2"
            }
        ]
    },
    {
        "id": "2",
        "salesInvoiceLines":
        [
            {
                "ItemCode": "Apple",
                "UnitCode": "piece",
                "Quantity": "20"
            },
            {
                "ItemCode": "Orange",
                "UnitCode": "piece",
                "Quantity": "21"
            },
            {
                "ItemCode": "Orange",
                "UnitCode": "box",
                "Quantity": "1"
            }
        ]
    }
    ]
}

我想按项目单位对将数据分组为以下格式:

[
  { item : 'Apple', unit : 'piece', totalQuantity : 30 },
  { item : 'Orange', unit : 'piece', totalQuantity : 21 },
  { item : 'Orange', unit : 'box', totalQuantity : 3 }
]

我使用 lodash 库厌倦了以下代码,但它不起作用

   var sumQuantity = function(total, item){
        return total + item.Quantity
    }
    var transformList = function(line){
        return _.map(line.SalesInvoiceLines, function(invoice){
            return _.map(invoice, function(line){
                return {
                    item: line.ItemCode,
                    unit: line.UnitCode,
                    totalQuantity: _.reduce(line.Quantity, sumQuantity, 0)
                }
            })
        });
    };
    var groupedList = _.groupBy(data.d.results, function(line) {
        return line.ItemCode + line.UnitCode;
    });
    var list = _.chain(groupedList)
    .map(transformList)
    .flatten()
    .value();

我怎样才能得到提到的结果?

抱歉,我不能给你一个具体的工作例子。据我所知,您的代码中存在以下概念错误:

  1. 我想最初的 groupBy 语句是错误的。假设 data.d.results 与您发布的示例 JSON 相同,那么您无法访问line.ItemCode + line.UnitCode;。相反,您只会获得一次迭代 salesInvoices .

  2. 您有一个不需要的 _.map 呼叫级别:

    return _.map(line.SalesInvoiceLines, function(invoice){ return _.map(invoice, function(line){

=> 发票已经是发票。迭代发票的属性没有意义(将它们称为line也没有意义)。

  1. totalQuantity: _.reduce(line.Quantity, sumQuantity, 0)中使用 _.reduce() 是没有意义的,因为line.Quantity已经是一个原始数字。你不能"减少"它。

我的建议是:

  1. 正确进行基本转换,并尝试将所有发票提取到平面数组中
  2. 然后你可以 _.reduce() 这个数组到一个中间对象,键按住 "line.项目代码 + 行。单元代码",指向您最终希望拥有的形式的对象,例如 { item : 'Apple', unit : 'piece', totalQuantity : 30 } .在每次 reduce 迭代中,您只需确定这个"唯一键",测试对象是否已经存在,如果没有,则使用 totalQuantity = 1 创建它,否则只需增加 totalQuantity。
  3. 最后,在步骤 2 的中间结果上调用 _.values()。
// Input
var data = {
    "salesInvoices": [{
        "id": "1",
        "salesInvoiceLines": [{
            "ItemCode": "Apple",
            "UnitCode": "piece",
            "Quantity": "10"
        }, {
            "ItemCode": "Orange",
            "UnitCode": "box",
            "Quantity": "2"
        }]
    }, {
        "id": "2",
        "salesInvoiceLines": [{
            "ItemCode": "Apple",
            "UnitCode": "piece",
            "Quantity": "20"
        }, {
            "ItemCode": "Orange",
            "UnitCode": "piece",
            "Quantity": "21"
        }, {
            "ItemCode": "Orange",
            "UnitCode": "box",
            "Quantity": "1"
        }]
    }]
}
//Output
/*
[
  { item : 'Apple', unit : 'piece', totalQuantity : 30 },
  { item : 'Orange', unit : 'piece', totalQuantity : 21 },
  { item : 'Orange', unit : 'box', totalQuantity : 3 }
]
*/
// Code
_.chain(_.flatten(_.map(data.salesInvoices, 'salesInvoiceLines')))
    .reduce(function(output, curr) {
        output[curr.ItemCode + '_' + curr.UnitCode] = output[curr.ItemCode + '_' + curr.UnitCode] ? output[curr.ItemCode + '_' + curr.UnitCode] + parseInt(curr.Quantity) : parseInt(curr.Quantity);
        return output;
    }, {})
    .reduce(function(result, value, key) {
        result.push({
            item: key.split('_')[0],
            unit: key.split('_')[1],
            totalQuantity: value
        });
        return result;
    }, []).value();

我能够使用以下代码做到这一点:

    var invoicelines = [];
    var lines = _.map(data, 'SalesInvoiceLines');
    var getLines = lines.forEach(function (entry){
        var l = entry.results;
        l.forEach(function (line){
            invoicelines.push(line);
        })
    });
    var list = _.chain(invoicelines)
       .groupBy(function(sll) {
            return sll.ItemCode + sll.UnitCode;
        })
        .map(function(value, key) {
            return [key, _.reduce(value, function(result, currentObject) {
                return {
                    Item: currentObject.ItemCode,
                    Unit: currentObject.UnitCode,
                    Quantity: result.Quantity + currentObject.Quantity
                }
            }, {
                Quantity: 0
            })];
        })
        .object()
        .sortBy(function(item) {
           return item.Quantity
        })
        .value();