使用 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"}
]
}
}
]
}
}
]
}
这里有一些东西可以让您接近您想要的东西。我将输出结构化为对象而不是数组。您的示例输出中不需要 industries
或 industry
属性。输出结构如下所示:
{
"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_
我是 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"}
]
}
}
]
}
}
]
}
这里有一些东西可以让您接近您想要的东西。我将输出结构化为对象而不是数组。您的示例输出中不需要 industries
或 industry
属性。输出结构如下所示:
{
"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_