Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用lodash转换集合_Javascript_Json_Collections_Lodash - Fatal编程技术网

Javascript 使用lodash转换集合

Javascript 使用lodash转换集合,javascript,json,collections,lodash,Javascript,Json,Collections,Lodash,我有一个查询,它给了我Json数据;例如,我有以下Json { "salesInvoices": [ { "id": "1", "salesInvoiceLines": [ { "ItemCode": "Apple", "UnitCode": "piece", "Quantity": "10"

我有一个查询,它给了我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();

我怎样才能得到上述结果?

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

  • 我猜最初的groupBy语句是错误的。假设data.d.results与您发布的示例JSON相同,则无法访问
    line.ItemCode+line.UnitCode那里。相反,您只需要对
    saleinvoices
    进行一次迭代

  • 您有一个级别的
    \.map
    调用,您不需要这些调用:

    return.map(line.SalesInvoiceLines,函数(发票){
    返回映射(发票,函数(行){

  • =>发票已经是发票。重复发票属性没有意义(调用它们
    行也没有意义)

  • totalQuantity:\u0.reduce(line.Quantity,sumQuantity,0)
    中使用u0.reduce()是没有意义的,因为
    line.Quantity
    已经是一个基本数。您不能“reduce”它
  • 我的建议是:

  • 正确地进行基本转换,并尝试将所有发票提取到平面数组中
  • 然后,您可以将这个数组u.reduce()转换为一个中间对象,键保持“line.ItemCode+line.UnitCode”,指向您希望最终拥有的形式的对象,例如,
    {item:'Apple',unit:'piece',totalQuantity:30}
    。在每次reduce迭代中,您只需确定这个“唯一键”,测试对象是否已经存在,如果不存在,则使用totalQuantity=1创建它,否则只需增加totalQuantity
  • 最后,对步骤2的中间结果调用u.values()

  • 我可以使用以下代码完成此操作:

        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();
    

    您的源JSON中已经有一个错误:属性
    salesInvoiceLines
    加倍,第二次出现将覆盖第一次出现。谢谢@Nic!我尝试实现您所说的内容。我会将其发布为答案。将答案标记为正确。这有助于人们了解答案。
    // 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();