Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/471.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript &引用;找不到未定义的属性名称;创建嵌套数据时_Javascript_Object_Ecmascript 6 - Fatal编程技术网

Javascript &引用;找不到未定义的属性名称;创建嵌套数据时

Javascript &引用;找不到未定义的属性名称;创建嵌套数据时,javascript,object,ecmascript-6,Javascript,Object,Ecmascript 6,我正在尝试使用现有数据集创建嵌套树对象。 原始数据集为: 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

我正在尝试使用现有数据集创建嵌套树对象。 原始数据集为:

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;  
}
为了解决这个问题,我尝试在ES6中使用
proxy
对象,而不是
var obj={}
,如下所示:

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”


我做错了什么?

您可以使用动态方法,将给定的键减少到最后一个元素,并将其作为赋值的访问器

在获取正确的内部对象的过程中,如果对象不存在,则会将默认对象指定给属性

函数设置值(对象、路径、值){
var last=path.pop();
reduce((o,k)=>o[k]=o[k]| |{},object)[last]=value;
返回对象;
}
var原始数据=[“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”、“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(对象)
。作为控制台包装{max height:100%!important;top:0;}
使用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}};
}
(i=0;i var[x,y,z,value]=原始数据[i]; obj[x]&&obj[x][y]?obj[x][y][z]=值:obj[x]?obj[x][y]={[z]:值}:obj[x]={[y]:{[z]:值}; }

多亏了ComputedPropertyName(请参阅)

这是我解决您问题的代码解决方案。我迭代了数组数组中的每个元素,并按照嵌套结构填充对象

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);
const原始数据=[
[“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]
];
设obj={};
原始数据。forEach(元素=>{

对于(设i=0;i当你第一次尝试访问
A1
键时,它不存在。因此你必须创建它。当你访问
A1
对象的
B1
键时,会发生完全相同的事情。是的,我需要在先前创建的引用上返回一个代理对象,但我不确定如何执行。你不知道你可以使用一个代理对象,但这是一个XY问题。本质上,你需要检查
obj[key]
是否存在,以及在与它交互之前它是否没有实例化它
obj[key]={}
。为什么所有的最终值
1
都在你想要的输出中。@MarkMeyer抱歉,这是一个输入错误。已编辑。
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);