2017-01-23 48 views
3

我试图重新集合一个复杂的对象数组。使用多个复合对象对数组项目进行组合

这里是我的数组:

[ 
    { 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统一我的数组,但我并没有得到预期的结果,那么获得一个没有重复项的数组的最有效方法是什么?

+0

的[什么是最有效的方法来GROUPBY对象的一个​​JavaScript阵列上?](HTTP可能重复:// stackoverflow.com/questions/14446511/what-is-the-most-efficient-method-to-groupby-on-a-javascript-array-of-objects) –

+0

可能,但我的数组和我的预期结果是更复杂的和回答并没有帮助我解决用户想要统一的其他问题中的问题Ÿ两个键在我的阵列中我有很多重复的键要统一 –

+0

请尝试http://stackoverflow.com/q/36196298/215552。这个问题和问题已经在SO上反复提出。 –

回答

1

您可以使用迭代方法,并为分组项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; }

+1

伟大的实现!但是如果代码清晰可读,这将会非常有用。 –

+0

好主意,你使用了一系列键的事实!这是我试图得到的结果! –

+0

以上的优点,它可以用于更多的按键/小孩,如果你需要它,而不需要改变主算法。 –

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

-1

人们也可以考虑实施只是使用查找为局部注射的鞋底集电极函数引用,因此,单个reduce迭代/周期内施加的,它已经聚集体/创建所需要的数据结构体。

如Nina的方法所证明的那样,实际上不需要将reduce循环嵌套到forEach迭代中,这也证明了后者的thisArgs的用法。 (不仅仅因为这很难读)。

热度的方法使用reduce,但每个迭代步骤中会有一个find是一个迭代过......最后的结果取决于喷气另外两个迭代,keysmap

人类可读代码示例...

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