«Не удается найти имя свойства неопределенного» при создании вложенных данных - PullRequest
0 голосов
/ 11 января 2019

Я пытаюсь создать объект вложенного дерева, используя существующий набор данных. Исходный набор данных:

var raw_data = [
["A1", "B1", "C1", 1],
["A1", "B1", "C2", 2],
["A1", "B2", "C1", 3],
["A1", "B2", "C1", 4],
["A1", "B2", "C2", 5],
["A1", "B2", "C2", 6],
["A2", "B1", "C1", 7],
["A2", "B1", "C1", 8],
["A2", "B1", "C2", 9],
["A2", "B1", "C2", 10],
["A2", "B2", "C1", 11],
["A2", "B2", "C1", 12],
["A2", "B2", "C2", 13],
["A2", "B2", "C2", 14]
];

Я хочу, чтобы мои окончательные данные выглядели так:

{'A1': 
  {'B1': {'C2': 2, 'C1': 1}, 
   'B2': {'C2': 6, 'C1': 4}
  }, 
 'A2': 
  {'B1': {'C2': 10, 'C1': 8}, 
   'B2': {'C2': 14, 'C1': 12}
  }
}

Вот мой прогресс на данный момент.

var obj = {};

for(i = 0; i< raw_data.length; i++) { 
  var [x,y,z,value] = raw_data[i];
  obj[x][y][z] = value;  
}

Я перебираю данные и рекурсивно запускаю значения свойств для пустых данных. Например: в 1-й итерации я установил obj['A1']['B1']['C1'] = 1. Однако это вызывает проблему, поскольку первая рекурсия (obj['A1']) вернет undefined, поэтому следующая ошибка:

"TypeError: Cannot set property 'B1' of undefined

Чтобы решить эту проблему, вместо var obj = {} я попытался использовать объект proxy в ES6 следующим образом:

var obj = new Proxy({}, { 
    get: function(target, name) {
        if (!(name in target)) {
            console.log("Non-existant property '" + name + "'");
            var val = target[name] = typeof(target);  //Returning reference to already created object
            return val;  
        }
    }
}); 

Однако теперь возвращается следующая ошибка: "TypeError: Невозможно установить свойство 'C1' из неопределенного

Что я здесь не так делаю?

Ответы [ 3 ]

0 голосов
/ 11 января 2019

С ES6 вы можете сделать

for(i = 0; i< raw_data.length; i++) { 
  var [x,y,z,value] = raw_data[i];

  obj[x] && obj[x][y] ? obj[x][y][z] = value : obj[x] ? obj[x][y] = {[z] : value} : obj[x] = {[y] : {[z] : value}};
}

Благодаря ComputedPropertyName (см. https://stackoverflow.com/a/2274327/3057341)

0 голосов
/ 11 января 2019

Вот мой код решения вашей проблемы. Я перебрал каждый элемент в массиве массивов и заполнил объект, следуя структуре вложенности.

const raw_data = [
    ["A1", "B1", "C1", 1],
    ["A1", "B1", "C2", 2],
    ["A1", "B2", "C1", 3],
    ["A1", "B2", "C1", 4],
    ["A1", "B2", "C2", 5],
    ["A1", "B2", "C2", 6],
    ["A2", "B1", "C1", 7],
    ["A2", "B1", "C1", 8],
    ["A2", "B1", "C2", 9],
    ["A2", "B1", "C2", 10],
    ["A2", "B2", "C1", 11],
    ["A2", "B2", "C1", 12],
    ["A2", "B2", "C2", 13],
    ["A2", "B2", "C2", 14]
    ];

let obj = {};
raw_data.forEach(element => {
    for(let i=0; i<4; i++){
        let first_elem = element[0];
        let second_elem = element[1];
        let third_elem = element[2];
        let fourth_elem = element[3];
        switch(i){
            case 0:
                if(!(first_elem in obj)){
                    obj[first_elem] = {};
                }
            break;
            case 1:
                if(!(second_elem in obj[first_elem])){
                    obj[first_elem][second_elem] = {};
                }
            break;
            case 2:
                if(!(third_elem in obj[first_elem][second_elem])){
                    obj[first_elem][second_elem][third_elem] = null;
                }
            break;
            case 3:
                if(fourth_elem != obj[first_elem][second_elem][third_elem]){
                    obj[first_elem][second_elem][third_elem] = fourth_elem;
                }
            break;
        }
    }  
});    
console.log(obj);
0 голосов
/ 11 января 2019

Вы можете использовать динамический подход и уменьшать количество заданных ключей до последнего элемента и использовать это как средство доступа для присвоения значения.

Внутри получения правильного внутреннего объекта объекту по умолчанию присваивается свойство, если объект не существует.

function setValue(object, path, value) {
    var last = path.pop();
    path.reduce((o, k) => o[k] = o[k] || {}, object)[last] = value;
    return object;
}

var raw_data = [["A1", "B1", "C1", 1], ["A1", "B1", "C1", 2], ["A1", "B1", "C2", 3], ["A1", "B2", "C1", 4], ["A1", "B2", "C1", 5], ["A1", "B2", "C2", 6], ["A1", "B2", "C2", 7], ["A2", "B1", "C1", 8], ["A2", "B1", "C1", 9], ["A2", "B1", "C2", 10], ["A2", "B1", "C2", 11], ["A2", "B2", "C1", 12], ["A2", "B2", "C1", 13], ["A2", "B2", "C2", 14], ["A2", "B2", "C2", 15]],
    object = raw_data.reduce((r, a) => setValue(r, a.slice(0, -1), a[a.length - 1]), {});

console.log(object);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...