使用 lodash 转换 JSON 响应

Transform JSON response with lodash

我是 lodash (v3.10.1) 的新手,很难理解。 希望有人能帮忙。

我有这样的输入:

{
     {"id":1,"name":"Matthew","company":{"id":1,"name":"abc","industry":{"id":5,"name":"Medical"}}},
     {"id":2,"name":"Mark","company":{"id":1,"name":"abc","industry":{"id":5,"name":"Medical"}}},
     {"id":3,"name":"Luke","company":{"id":1,"name":"abc","industry":{"id":5,"name":"Medical"}}},
     {"id":4,"name":"John","company":{"id":1,"name":"abc","industry":{"id":5,"name":"Medical"}}},
     {"id":5,"name":"Paul","company":{"id":1,"name":"abc","industry":{"id":5,"name":"Medical"}}}
];

我想输出这个或接近这个:

{
     "industries": [
        {
            "industry":{
                "id":5,
                "name":"Medical",
                "companies": [
                    {
                        "company":{
                            "id":1,
                            "name":"abc",
                            "employees": [
                                {"id":1,"name":"Matthew"},
                                {"id":2,"name":"Mark"},
                                {"id":3,"name":"Luke"},
                                {"id":4,"name":"John"},
                                {"id":5,"name":"Paul"}
                            ]
                        }
                    }
                ]
            }
        }
    ]
}

这里有一些东西可以让您接近您想要的东西。我将输出结构化为对象而不是数组。您的示例输出中不需要 industriesindustry 属性。输出结构如下所示:

{
  "industry name": {
    "id": "id of industry",
    "companies": [
      {
        "company name": "name of company",
        "id": "id of company",
        "employees": [
          {
            "id": "id of company",
            "name": "name of employee"
          }
        ]
      }
    ]
  }
}

我使用 _.chain 函数用 lodash 包装器对象包装集合。这使我能够明确地链接 lodash 函数。

从那里,我使用 _.groupBy 函数按行业名称对集合中的元素进行分组。由于我正在链接,所以我不必再次将数组传递给函数。它通过 lodash 包装器隐式传递。 _.groupBy 的第二个参数是我要作为元素分组依据的值的路径。在本例中,它是行业名称的路径:company.industry.name_.groupBy returns 每个员工按行业分组的对象(行业是该对象的键)。

然后我确实使用 _.transform 来转换每个行业对象。 _.transform 本质上是 _.reduce 除了从 _.transform 函数返回的结果总是一个对象。

传递给 _.transform 函数的函数针对对象中的每个 key/value 对执行。在函数中,我再次使用 _.groupBy 按公司对员工进行分组。根据 _.groupBy 的结果,我将这些值映射到我想要的每个员工对象的最终结构。

然后我调用 _.value 函数,因为我想从 lodash 包装器对象中解包输出集合。

我希望这是有道理的。如果没有,我强烈建议阅读 Lo-Dash Essentials。看完书,终于明白为什么lodash这么好用了。

"use strict";

var _ = require('lodash');

var emps = [
  { "id": 1, "name": "Matthew", "company": { "id": 1, "name": "abc", "industry": { "id": 5, "name": "Medical" } } },
  { "id": 2, "name": "Mark", "company": { "id": 1, "name": "abc", "industry": { "id": 5, "name": "Medical" } } },
  { "id": 3, "name": "Luke", "company": { "id": 1, "name": "abc", "industry": { "id": 5, "name": "Medical" } } },
  { "id": 4, "name": "John", "company": { "id": 1, "name": "abc", "industry": { "id": 5, "name": "Medical" } } },
  { "id": 5, "name": "Paul", "company": { "id": 1, "name": "abc", "industry": { "id": 5, "name": "Medical" } } }
];

var result = _.chain(emps)
  .groupBy("company.industry.name")
  .transform(function(result, employees, industry) {
    result[industry] = {};
    result[industry].id = _.get(employees[0], "company.industry.id");

    result[ industry ][ 'companies' ] = _.map(_.groupBy(employees, "company.name"), function( employees, company ) {
      return {
        company: company,
        id: _.get(employees[ 0 ], 'company.id'),
        employees: _.map(employees, _.partialRight(_.pick, [ 'id', 'name' ]))
      };
    });
    return result;
  })
  .value();

您的示例结果如下:

{
  "Medical": {
    "id": 5,
    "companies": [
      {
        "company": "abc",
        "id": 1,
        "employees": [
          {
            "id": 1,
            "name": "Matthew"
          },
          {
            "id": 2,
            "name": "Mark"
          },
          {
            "id": 3,
            "name": "Luke"
          },
          {
            "id": 4,
            "name": "John"
          },
          {
            "id": 5,
            "name": "Paul"
          }
        ]
      }
    ]
  }
}

如果您想要与问题中完全相同的结构,我使用 jsonata 库解决了它:

(
    /* lets flatten it out for ease of accessing the properties*/
    $step1 :=    $ ~> | $ | 
            {
                "employee_id": id,
                "employee_name": name,
                "company_id": company.id,
                "company_name": company.name,
                "industry_id": company.industry.id,
                "industry_name": company.industry.name        
            }, 
            ["company", "id", "name"] |;
    
    /* now the magic begins*/
    $step2 := {
        "industries": 
            [($step1{                
                "industry" & $string(industry_id): ${
                    "id": $distinct(industry_id)@$I,
                    "name": $distinct(industry_name),
                    "companies": [({
                        "company" & $string(company_id): {
                            "id": $distinct(company_id),
                            "name": $distinct(company_name),
                            "employees": [$.{                                
                                    "id": $distinct(employee_id),
                                    "name": $distinct(employee_name)
                                
                            }]
                        }
                    } ~> $each(function($v){ {"company": $v} }))]
                }
                
            } ~> $each(function($v){ {"industry": $v} }))]
        
    };    
)

您可以在现场演示网站上看到它的实际效果:https://try.jsonata.org/VvW4uTRz_