首页 > 解决方案 > 在 JavaScript 中将数据动态写入嵌套对象

问题描述

我想动态地将数据(以对象的形式)作为值写入嵌套在另一个对象中的对象;并且还可以动态创建键的名称(在循环内)。

我当前的代码如下所示:

data = {'x': 2, 'y': 3}

master_obj = {'useless': {}, 'important': {}}

var block_ind = 0
let trials = 12
let trials_per_block = 4
for (trial_ind=0; trial_ind<trials; trial_ind++) {
    // every 4 trials are in a new block
    block_ind = trial_ind % trials_per_block == 0 ? trial_ind/trials_per_block : block_ind
    
    master_obj['important']['block_0'+block_ind] = {}
    master_obj['important']['block_0'+block_ind]['trial_0'+trial_ind] = data
}
console.log(master_obj)

代码的输出如下所示(也可以在上面运行代码段): 上述代码段的输出

而预期的输出是[在一个块内进行多次试验,而不是一次]:

useless: {}
important:
    block_00:
        trial_00: {x: 2, y:3}
        trial_01: {x: 2, y:3}
        trial_02: {x: 2, y:3}
        trial_03: {x: 2, y:3}
    block_01:
        trial_04: {x: 2, y:3}
        trial_05: {x: 2, y:3}
        trial_06: {x: 2, y:3}
        trial_07: {x: 2, y:3}
    block_02:
        trial_08: {x: 2, y:3}
        trial_09: {x: 2, y:3}
        trial_10: {x: 2, y:3}
        trial_11: {x: 2, y:3}

感谢您提供任何和所有帮助和建议!

标签: javascriptobjectdynamic

解决方案


问题是你不是在复制data,你只是在重用同一个对象。另一个问题是,当您尝试将另一个实例添加到现有块时,您正在覆盖之前创建的对象。

如何复制它是一个潜在的复杂主题(请参阅此问题的答案),但对于它自己的可枚举属性的浅拷贝,您可以使用扩展符号或Object.assign对象文字,请参见***下面的行:

const data = {"x": 2, "y": 3}

const master_obj = {"useless": {}, "important": {}}

var block_ind = 0
let trials = 12
let trials_per_block = 4
const important = master_obj.important; // *** No need to repeat this
for (let trial_ind=0; trial_ind<trials; trial_ind++) {
//   ^^^−−−− *** Declare your variables
    // every 4 trials are in a new block
    block_ind = trial_ind % trials_per_block == 0 ? trial_ind/trials_per_block : block_ind

    // *** Only create this if it doesn't exist
    if (!important["block_0"+block_ind]) {
        important["block_0"+block_ind] = {}
    }
    important["block_0"+block_ind]["trial_0"+trial_ind] = {...data} // ***
}
console.log(master_obj)

另请注意,我添加constdatamaster_obj。如果没有let,const或, 你的代码就会沦为我所说的隐式全局恐怖的var牺牲品。一定要声明你的变量。(我建议始终使用or ,从不使用。)constletvar


对于它的价值,您可以使用Math.floor(trial_ind / trials_per_block)来确定块号。这是加上几个模板文字和其他具有描述性名称的常量:

const data = {"x": 2, "y": 3};

const master_obj = {"useless": {}, "important": {}};

const trials = 12;
const trials_per_block = 4;
const important = master_obj.important;
for (let trial_ind = 0; trial_ind < trials; ++trial_ind) {
    // Every 4 trials are in a new block
    const blockKey = `block_0${Math.floor(trial_ind / trials_per_block)}`;

    const trialKey = `trial_0${trial_ind}`;

    if (!important[blockKey]) {
        important[blockKey] = {};
    }
    important[blockKey][trialKey] = {...data};
}
console.log(master_obj);


推荐阅读