使用多个复杂对象对数组项进行分组
Group array items using multiple and complexe object
我正在尝试重新组合一个复杂的对象数组。
这是我的数组:
[
{ scenario: "Treasury", diagnostic: "good results", action: "Manage Financial Recovery"},
{ scenario: "Treasury", diagnostic: "good results", action: "Analyze the impact of your investments"},
{ scenario: "Treasury", diagnostic: "Significant decline", action: "Ensure an adequate"},
{ scenario: "Treasury", diagnostic: "Significant decline", action: "Pilot your cash"},
{ scenario: "Turnover", diagnostic: "Improve trade efficiency of your business", action: "Valorize your labels"},
{ scenario: "Turnover", diagnostic: "Improve trade efficiency of your business", action: "Analyze the opportunity"}
{ scenario: "Turnover", diagnostic: "Improve trade efficiency of your firm", action: "Contacter un prestataire"}
];
我想将上面的数组统一到这个:
[
{
scenario: "Treasury",
diagnostics: [
{
diagnostic : "good results",
actions: [
"Manage Financial Recovery",
"Analyze the impact of your investments"
]
}
{
diagnostic : "Significant decline",
actions: [
"Ensure an adequate",
"Pilot your cash"
]
}
]
},
{
scenario: "Turnover",
diagnostics: [
{
diagnostic : "Improve trade efficiency of your business",
actions: [
"Valorize your labels",
"Analyze the opportunity"
]
}
{
diagnostic : "Improve trade efficiency of your firm",
actions: [
"Contacter un prestataire"
]
}
]
}
];
所以我尝试使用 JSBin 来统一我的数组,但我没有得到预期的结果,那么获得没有重复对象的数组的最有效方法是什么。
您可以使用迭代方法并为 key
的分组项目使用辅助对象。
function getGrouped(array, keys, groupCB, children) {
var result = [],
hash = { _: result };
groupCB = groupCB || function (o) { return o; };
children = children || [];
array.forEach(function (a) {
keys.reduce(function (r, k, i) {
var o = {};
if (!r[a[k]]) {
r[a[k]] = { _: [] };
o[k] = a[k];
o[children[i] || 'children'] = r[a[k]]._;
r._.push(o);
}
return r[a[k]];
}, hash)._.push(groupCB(a));
});
return result;
}
var data = [{ scenario: "Treasury", diagnostic: "good results", action: "Manage Financial Recovery" }, { scenario: "Treasury", diagnostic: "good results", action: "Analyze the impact of your investments" }, { scenario: "Treasury", diagnostic: "Significant decline", action: "Ensure an adequate" }, { scenario: "Treasury", diagnostic: "Significant decline", action: "Pilot your cash" }, { scenario: "Turnover", diagnostic: "Improve trade efficiency of your business", action: "Valorize your labels" }, { scenario: "Turnover", diagnostic: "Improve trade efficiency of your business", action: "Analyze the opportunity" }, { scenario: "Turnover", diagnostic: "Improve trade efficiency of your firm", action: "Contacter un prestataire" }],
groupCB = function (o) { return o.action },
keys = ['scenario', 'diagnostic'],
children = ['diagnostics', 'actions'],
result = getGrouped(data, keys, groupCB, children);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
您可以进行如下操作:;
var data = [ { scenario: "Treasury", diagnostic: "good results", action: "Manage Financial Recovery"},
{ scenario: "Treasury", diagnostic: "good results", action: "Analyze the impact of your investments"},
{ scenario: "Treasury", diagnostic: "Significant decline", action: "Ensure an adequate"},
{ scenario: "Treasury", diagnostic: "Significant decline", action: "Pilot your cash"},
{ scenario: "Turnover", diagnostic: "Improve trade efficiency of your business", action: "Valorize your labels"},
{ scenario: "Turnover", diagnostic: "Improve trade efficiency of your business", action: "Analyze the opportunity"},
{ scenario: "Turnover", diagnostic: "Improve trade efficiency of your firm", action: "Contacter un prestataire"}
],
hash = data.reduce(function(p,c){
var fd = null;
p[c.scenario] = p[c.scenario] ? (fd = p[c.scenario].diagnostics.find(d => d.diagnostic === c.diagnostic),
fd ? (fd.action.push(c.action),p[c.scenario])
: (p[c.scenario].diagnostics.push({diagnostic: c.diagnostic, action: [c.action]}),p[c.scenario]))
: {scenario: c.scenario, diagnostics: [{diagnostic: c.diagnostic, action: [c.action]}]};
return p;
},{});
result = Object.keys(hash).map(k => hash[k]);
console.log(JSON.stringify(result,null,4));
也可以考虑实现一个单独的收集器函数,该函数仅使用查找本地注入的引用,因此,在单个 reduce
iteration/cycle 中应用,它已经 aggregates/creates 所需的数据结构。
确实没有必要将 reduce
循环嵌套到 forEach
迭代中,正如 Nina 的方法所证明的那样,它也大大改变了后者 thisArgs
的用法。 (不仅因为它很难阅读)。
Redu 的方法使用 reduce
,但是在每个迭代步骤中都会有一个 find
也是一个迭代器...最终结果取决于 jet 另外两次迭代,keys
和 map
.
人类可读的示例代码...
var diagnosticData = [
{ scenario: "Treasury", diagnostic: "good results", action: "Manage Financial Recovery"},
{ scenario: "Treasury", diagnostic: "good results", action: "Analyze the impact of your investments"},
{ scenario: "Treasury", diagnostic: "Significant decline", action: "Ensure an adequate"},
{ scenario: "Treasury", diagnostic: "Significant decline", action: "Pilot your cash"},
{ scenario: "Turnover", diagnostic: "Improve trade efficiency of your business", action: "Valorize your labels"},
{ scenario: "Turnover", diagnostic: "Improve trade efficiency of your business", action: "Analyze the opportunity"},
{ scenario: "Turnover", diagnostic: "Improve trade efficiency of your firm", action: "Contacter un prestataire"}
];
function collectGroupedScenarioDiagnostics(collector, diagnosticItem/*, idx, list*/) {
var
scenarioKey = diagnosticItem.scenario,
diagnosticKey = diagnosticItem.diagnostic,
groupedDiagnosticKey = [scenarioKey, diagnosticKey].join(' : '),
scenarioItem = collector.scenarioStore[scenarioKey],
groupedDiagnosticItem = collector.diagnosticStore[groupedDiagnosticKey];
if (!scenarioItem) {
scenarioItem = collector.scenarioStore[scenarioKey] = {
scenario : scenarioKey,
diagnostics : []
};
collector.diagnosticsList.push(scenarioItem);
}
if (!groupedDiagnosticItem) {
groupedDiagnosticItem = collector.diagnosticStore[groupedDiagnosticKey] = {
diagnostic: diagnosticKey,
actions : []
};
scenarioItem.diagnostics.push(groupedDiagnosticItem);
}
groupedDiagnosticItem.actions.push(diagnosticItem.action);
return collector;
}
var groupedScenarioDiagnostics = diagnosticData.reduce(collectGroupedScenarioDiagnostics, {
scenarioStore : {},
diagnosticStore : {},
diagnosticsList : []
}).diagnosticsList;
console.log('groupedScenarioDiagnostics : ', groupedScenarioDiagnostics);
我正在尝试重新组合一个复杂的对象数组。
这是我的数组:
[
{ scenario: "Treasury", diagnostic: "good results", action: "Manage Financial Recovery"},
{ scenario: "Treasury", diagnostic: "good results", action: "Analyze the impact of your investments"},
{ scenario: "Treasury", diagnostic: "Significant decline", action: "Ensure an adequate"},
{ scenario: "Treasury", diagnostic: "Significant decline", action: "Pilot your cash"},
{ scenario: "Turnover", diagnostic: "Improve trade efficiency of your business", action: "Valorize your labels"},
{ scenario: "Turnover", diagnostic: "Improve trade efficiency of your business", action: "Analyze the opportunity"}
{ scenario: "Turnover", diagnostic: "Improve trade efficiency of your firm", action: "Contacter un prestataire"}
];
我想将上面的数组统一到这个:
[
{
scenario: "Treasury",
diagnostics: [
{
diagnostic : "good results",
actions: [
"Manage Financial Recovery",
"Analyze the impact of your investments"
]
}
{
diagnostic : "Significant decline",
actions: [
"Ensure an adequate",
"Pilot your cash"
]
}
]
},
{
scenario: "Turnover",
diagnostics: [
{
diagnostic : "Improve trade efficiency of your business",
actions: [
"Valorize your labels",
"Analyze the opportunity"
]
}
{
diagnostic : "Improve trade efficiency of your firm",
actions: [
"Contacter un prestataire"
]
}
]
}
];
所以我尝试使用 JSBin 来统一我的数组,但我没有得到预期的结果,那么获得没有重复对象的数组的最有效方法是什么。
您可以使用迭代方法并为 key
的分组项目使用辅助对象。
function getGrouped(array, keys, groupCB, children) {
var result = [],
hash = { _: result };
groupCB = groupCB || function (o) { return o; };
children = children || [];
array.forEach(function (a) {
keys.reduce(function (r, k, i) {
var o = {};
if (!r[a[k]]) {
r[a[k]] = { _: [] };
o[k] = a[k];
o[children[i] || 'children'] = r[a[k]]._;
r._.push(o);
}
return r[a[k]];
}, hash)._.push(groupCB(a));
});
return result;
}
var data = [{ scenario: "Treasury", diagnostic: "good results", action: "Manage Financial Recovery" }, { scenario: "Treasury", diagnostic: "good results", action: "Analyze the impact of your investments" }, { scenario: "Treasury", diagnostic: "Significant decline", action: "Ensure an adequate" }, { scenario: "Treasury", diagnostic: "Significant decline", action: "Pilot your cash" }, { scenario: "Turnover", diagnostic: "Improve trade efficiency of your business", action: "Valorize your labels" }, { scenario: "Turnover", diagnostic: "Improve trade efficiency of your business", action: "Analyze the opportunity" }, { scenario: "Turnover", diagnostic: "Improve trade efficiency of your firm", action: "Contacter un prestataire" }],
groupCB = function (o) { return o.action },
keys = ['scenario', 'diagnostic'],
children = ['diagnostics', 'actions'],
result = getGrouped(data, keys, groupCB, children);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
您可以进行如下操作:;
var data = [ { scenario: "Treasury", diagnostic: "good results", action: "Manage Financial Recovery"},
{ scenario: "Treasury", diagnostic: "good results", action: "Analyze the impact of your investments"},
{ scenario: "Treasury", diagnostic: "Significant decline", action: "Ensure an adequate"},
{ scenario: "Treasury", diagnostic: "Significant decline", action: "Pilot your cash"},
{ scenario: "Turnover", diagnostic: "Improve trade efficiency of your business", action: "Valorize your labels"},
{ scenario: "Turnover", diagnostic: "Improve trade efficiency of your business", action: "Analyze the opportunity"},
{ scenario: "Turnover", diagnostic: "Improve trade efficiency of your firm", action: "Contacter un prestataire"}
],
hash = data.reduce(function(p,c){
var fd = null;
p[c.scenario] = p[c.scenario] ? (fd = p[c.scenario].diagnostics.find(d => d.diagnostic === c.diagnostic),
fd ? (fd.action.push(c.action),p[c.scenario])
: (p[c.scenario].diagnostics.push({diagnostic: c.diagnostic, action: [c.action]}),p[c.scenario]))
: {scenario: c.scenario, diagnostics: [{diagnostic: c.diagnostic, action: [c.action]}]};
return p;
},{});
result = Object.keys(hash).map(k => hash[k]);
console.log(JSON.stringify(result,null,4));
也可以考虑实现一个单独的收集器函数,该函数仅使用查找本地注入的引用,因此,在单个 reduce
iteration/cycle 中应用,它已经 aggregates/creates 所需的数据结构。
确实没有必要将 reduce
循环嵌套到 forEach
迭代中,正如 Nina 的方法所证明的那样,它也大大改变了后者 thisArgs
的用法。 (不仅因为它很难阅读)。
Redu 的方法使用 reduce
,但是在每个迭代步骤中都会有一个 find
也是一个迭代器...最终结果取决于 jet 另外两次迭代,keys
和 map
.
人类可读的示例代码...
var diagnosticData = [
{ scenario: "Treasury", diagnostic: "good results", action: "Manage Financial Recovery"},
{ scenario: "Treasury", diagnostic: "good results", action: "Analyze the impact of your investments"},
{ scenario: "Treasury", diagnostic: "Significant decline", action: "Ensure an adequate"},
{ scenario: "Treasury", diagnostic: "Significant decline", action: "Pilot your cash"},
{ scenario: "Turnover", diagnostic: "Improve trade efficiency of your business", action: "Valorize your labels"},
{ scenario: "Turnover", diagnostic: "Improve trade efficiency of your business", action: "Analyze the opportunity"},
{ scenario: "Turnover", diagnostic: "Improve trade efficiency of your firm", action: "Contacter un prestataire"}
];
function collectGroupedScenarioDiagnostics(collector, diagnosticItem/*, idx, list*/) {
var
scenarioKey = diagnosticItem.scenario,
diagnosticKey = diagnosticItem.diagnostic,
groupedDiagnosticKey = [scenarioKey, diagnosticKey].join(' : '),
scenarioItem = collector.scenarioStore[scenarioKey],
groupedDiagnosticItem = collector.diagnosticStore[groupedDiagnosticKey];
if (!scenarioItem) {
scenarioItem = collector.scenarioStore[scenarioKey] = {
scenario : scenarioKey,
diagnostics : []
};
collector.diagnosticsList.push(scenarioItem);
}
if (!groupedDiagnosticItem) {
groupedDiagnosticItem = collector.diagnosticStore[groupedDiagnosticKey] = {
diagnostic: diagnosticKey,
actions : []
};
scenarioItem.diagnostics.push(groupedDiagnosticItem);
}
groupedDiagnosticItem.actions.push(diagnosticItem.action);
return collector;
}
var groupedScenarioDiagnostics = diagnosticData.reduce(collectGroupedScenarioDiagnostics, {
scenarioStore : {},
diagnosticStore : {},
diagnosticsList : []
}).diagnosticsList;
console.log('groupedScenarioDiagnostics : ', groupedScenarioDiagnostics);