Я пытаюсь преобразовать эту структуру:Javascript преобразовать массив объектов в дереве
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 example = {
"Phase 1": {
"Step 1": {
"Task 1": { Phase: "Phase 1", Step: "Step 1", Task: "Task 1", Value: "5" },
"Task 2": { Phase: "Phase 1", Step: "Step 1", Task: "Task 2", Value: "10" }
} ,
"Step 2": {
"Task 1": { Phase: "Phase 1", Step: "Step 2", Task: "Task 1", Value: "15" },
"Task 2": { Phase: "Phase 1", Step: "Step 2", Task: "Task 2", Value: "20" }
}
} ,
"Phase 2": {
"Step 1": {
"Task 1": { Phase: "Phase 2", Step: "Step 1", Task: "Task 1", Value: "25" },
"Task 2": { Phase: "Phase 2", Step: "Step 1", Task: "Task 2", Value: "30" },
} ,
"Step 2": {
"Task 1": { Phase: "Phase 2", Step: "Step 2", Task: "Task 1", Value: "35" },
"Task 2": { Phase: "Phase 2", Step: "Step 2", Task: "Task 2", Value: "40" }
}
}
};
так что я могу легко извлечь значение, как этот example['Phase 2']['Step 1']['Task 1']['Value']
Я сделал первый шаг, используя функцию groupBy
, подобную этой:
function groupBy(d, arr) {
return arr.reduce(function(acc, i) {
var p = i[d];
var temp = acc[p] || [];
temp.push(i);
acc[p] = temp;
return acc;
}, {})
}
так, когда я var groupedByPhase = groupBy('Phase', initial);
я получаю за groupedByPhase
:
{
"Phase 1" : [
{ 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 2": [
{ 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" }
]
}
Я также умудряются группы за шагом, используя эту функцию:
function groupByInNestedObj(item, obj) {
var x = {};
for (var i in obj) {
x[i] = groupBy(item, obj[i]);
}
return x;
}
, которая позволяет получить при вызове groupByInNestedObj('Step', groupBy('Phase', initial))
{
"Phase 1" : {
"Step 1": [
{ Phase: "Phase 1", Step: "Step 1", Task: "Task 1", Value: "5" },
{ Phase: "Phase 1", Step: "Step 1", Task: "Task 2", Value: "10" }],
"Step 2": [
{ Phase: "Phase 1", Step: "Step 2", Task: "Task 1", Value: "15" },
{ Phase: "Phase 1", Step: "Step 2", Task: "Task 2", Value: "20" },
]},
"Phase 2": {
"Step 1:" [
{ Phase: "Phase 2", Step: "Step 1", Task: "Task 1", Value: "25" },
{ Phase: "Phase 2", Step: "Step 1", Task: "Task 2", Value: "30" }],
"Step 2:"[
{ Phase: "Phase 2", Step: "Step 2", Task: "Task 1", Value: "35" },
{ Phase: "Phase 2", Step: "Step 2", Task: "Task 2", Value: "40" }
]}
}
Однако я немного uck здесь, чтобы сделать следующий. В идеале я хотел бы иметь возможность делать groupBy("Task", groupBy("Step", groupBy("Phase", initial)))
так, чтобы groupBy группировался на самом глубоком уровне дерева. Любые предложения приветствуются!
Примечание: Я стараюсь для второго шага для реализации этой функции
function groupByInNestedObj2 (item, obj) {
var x = {};
for(var i in obj) {
for (var j in obj[i]) {
x[i][j] = groupBy(item, obj[i][j]);
}
}
return x;
}
, но это не похоже на работу.
Примечание 2: Вторая версия предыдущей функции работает, но не является чистым, как она изменяет объект, переданный через него
function groupByInNestedObj2 (item, obj) {
var x = {};
for(var i in obj) {
x[i] = obj[i]
for (var j in x[i]) {
x[i][j] = groupBy('Task', x[i][j]);
}
}
return x;
}
так, когда я var groupByPhaseAndStepAndTask = groupByInNestedObj2('Task', groupByPhaseAndStep)
groupByPhaseAndStep модифицирован тоже, что является нежелательным побочный эффект. Все еще работаю над этим.
Это довольно близко к желаемому результату, внутри задач объекты не массивы, но это было бы нормально. Хотя я использую lodash для некоторых вещей, я не слишком знаком с _.mixin, поэтому в вашем ответе почти слишком много магии. Кроме того, я стараюсь достичь состава функции, поэтому я могу сделать что-то вроде 'groupBy (« Task », groupBy (« Step », groupBy (« Phase », initial))) – Bondifrench
Хорошо, мне удалось это сделать, рефакторинг вашего примера , используя простые функции head, tail и groupBy, мне нравится использование рекурсии, теперь просто нужно ее изменить, поэтому, когда array.length == 1, я получаю объект, а не массив с одним элементом – Bondifrench