Skip to content Skip to sidebar Skip to footer

Javascript Convert Array Of Objects To Tree

I am trying to convert this structure: var initial = [ { Phase: 'Phase 1', Step: 'Step 1', Task: 'Task 1', Value: '5' }, { Phase: 'Phase 1', Step: 'Step 1', Task: 'Task 2', Value:

Solution 1:

You can try use .reduce and just check if object exists or not, like this

var initial = [ 
  { Phase: "Phase 1", Step: "Step 1", Task: "Task 1", Value: "5" },
  { Phase: "Phase 1", Step: "Step 1", Task: "Task 2", Value: "10" },
  { Phase: "Phase 1", Step: "Step 2", Task: "Task 1", Value: "15" },
  { Phase: "Phase 1", Step: "Step 2", Task: "Task 2", Value: "20" },
  { Phase: "Phase 2", Step: "Step 1", Task: "Task 1", Value: "25" },
  { Phase: "Phase 2", Step: "Step 1", Task: "Task 2", Value: "30" },
  { Phase: "Phase 2", Step: "Step 2", Task: "Task 1", Value: "35" },
  { Phase: "Phase 2", Step: "Step 2", Task: "Task 2", Value: "40" }
];

var result = initial.reduce(function (prev, current) {
  prev[current.Phase] = prev[current.Phase] || {};
  prev[current.Phase][current.Step] = prev[current.Phase][current.Step] || {};
  prev[current.Phase][current.Step][current.Task] = current;
  return prev;
}, {});

console.log(JSON.stringify(result, null, 2));

Solution 2:

We can do it this with a single for loop:

var initial = [ 
{ Phase: "Phase 1", Step: "Step 1", Task: "Task 1", Value: "5" },
{ Phase: "Phase 1", Step: "Step 1", Task: "Task 2", Value: "10" },
{ Phase: "Phase 1", Step: "Step 2", Task: "Task 1", Value: "15" },
{ Phase: "Phase 1", Step: "Step 2", Task: "Task 2", Value: "20" },
{ Phase: "Phase 2", Step: "Step 1", Task: "Task 1", Value: "25" },
{ Phase: "Phase 2", Step: "Step 1", Task: "Task 2", Value: "30" },
{ Phase: "Phase 2", Step: "Step 2", Task: "Task 1", Value: "35" },
{ Phase: "Phase 2", Step: "Step 2", Task: "Task 2", Value: "40" }
];
var final = {}
initial.forEach(function(d){
  if (!final[d.Phase]) //phase not present so make an object
  	final[d.Phase] = {};
  if (!final[d.Phase][d.Step]) //step not present so make an object
  	final[d.Phase][d.Step] = {};
  if (!final[d.Phase][d.Step][d.Task])//task not present so make an object and store the object
  	final[d.Phase][d.Step][d.Task] = d;
  
})
console.log(final)

Solution 3:

A more generic way using lodash and this answer:

var initial = [
  { Phase: "Phase 1", Step: "Step 1", Task: "Task 1", Value: "5" },
  { Phase: "Phase 1", Step: "Step 1", Task: "Task 2", Value: "10" },
  { Phase: "Phase 1", Step: "Step 2", Task: "Task 1", Value: "15" },
  { Phase: "Phase 1", Step: "Step 2", Task: "Task 2", Value: "20" },
  { Phase: "Phase 2", Step: "Step 1", Task: "Task 1", Value: "25" },
  { Phase: "Phase 2", Step: "Step 1", Task: "Task 2", Value: "30" },
  { Phase: "Phase 2", Step: "Step 2", Task: "Task 1", Value: "35" },
  { Phase: "Phase 2", Step: "Step 2", Task: "Task 2", Value: "40" }
];

_.mixin({
  groupByMulti: function(obj, values, context) {
    if (!values.length) return obj;
    var byFirst = _.groupBy(obj, _.head(values), context);
    for (var prop in byFirst) {
      byFirst[prop] = _.groupByMulti(byFirst[prop], _.tail(values), context);
    }
    return byFirst;
  }
});

var tree = _(initial).groupByMulti(['Phase', 'Step', 'Task']);
$('#pre').append(JSON.stringify(tree, null, 3));
<scriptsrc="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.0.0/lodash.min.js"></script><scriptsrc="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><preid='pre'></pre>

Post a Comment for "Javascript Convert Array Of Objects To Tree"