【问题标题】:Dynamically writing data into nested objects in JavaScript在 JavaScript 中将数据动态写入嵌套对象
【发布时间】:2021-06-08 09:08:17
【问题描述】:

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

我当前的代码如下所示:

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)

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

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

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}

感谢任何和所有的帮助和建议!

【问题讨论】:

    标签: javascript object dynamic


    【解决方案1】:

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

    如何复制它是一个潜在的复杂主题(请参阅this question's answers),但对于它自己的可枚举属性的浅拷贝,您可以使用扩展符号或 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)

    另外请注意,我在datamaster_obj 上添加了const。如果没有letconstvar,您的代码就会成为我所说的The Horror of Implicit Globals 的牺牲品。一定要声明你的变量。 (我建议始终使用constlet,不要使用var。)


    对于它的价值,您可以使用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);

    【讨论】:

    • 感谢您的意见@T.J.克劳德!我认为这与 JavaScript 如何处理引用有关,但我并没有完全理解。不幸的是,按照您的建议复制data 的内容仍然无法获得我想要的输出,因为我想在每个块中创建更多的键值对(不仅仅是嵌套在单个块中的单个试验)。跨度>
    • @npetrov937 - 我意识到我建议的是更简洁的版本。我已经更新了答案,我认为它会产生你现在正在寻找的东西。
    • 太棒了!谢谢!因此,我在每个循环中都创建了块,并在其中创建了一个新的试验对象,因此它被覆盖了。非常感谢您的有益建议;非常感谢他们!
    • @npetrov937 - 我很高兴。 FWIW,我在答案的末尾添加了更多内容。编码愉快!
    猜你喜欢
    • 2020-12-11
    • 2020-05-22
    • 2021-11-17
    • 2020-07-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-01
    • 1970-01-01
    相关资源
    最近更新 更多