【问题标题】:Javascript: how to dynamically create nested objects using object names given by an arrayJavascript:如何使用数组给出的对象名称动态创建嵌套对象
【发布时间】:2011-07-25 23:24:00
【问题描述】:

我希望有人可以帮助我处理这个 Javascript。

我有一个名为“设置”的对象,我想编写一个向该对象添加新设置的函数。

新设置的名称和值以字符串形式提供。然后将给出设置名称的字符串用下划线分割成一个数组。新设置应该通过创建新的嵌套对象添加到现有的“设置”对象中,该对象的名称由数组的每个部分给出,除了最后一部分应该是一个给出设置值的字符串。然后我应该能够参考设置,例如提醒它的价值。我可以像这样以静态方式做到这一点......

var Settings = {};
var newSettingName = "Modules_Video_Plugin";
var newSettingValue = "JWPlayer";
var newSettingNameArray = newSettingName.split("_");

Settings[newSettingNameArray[0]] = {};
Settings[newSettingNameArray[0]][newSettingNameArray[1]] = {};
Settings[newSettingNameArray[0]][newSettingNameArray[1]][newSettingNameArray[2]] = newSettingValue;

alert(Settings.Modules.Mediaplayers.Video.Plugin);

...创建嵌套对象的部分正在执行此操作...

Settings["Modules"] = {};
Settings["Modules"]["Video"] = {};
Settings["Modules"]["Video"]["Plugin"] = "JWPlayer";

但是,由于构成设置名称的部分数量可能会有所不同,例如newSettingName 可以是“Modules_Floorplan_Image_Src”,我想使用诸如...的函数动态地执行此操作。

createSetting (newSettingNameArray, newSettingValue);

function createSetting(setting, value) {
    // code to create new setting goes here
}

谁能帮我弄清楚如何动态地做到这一点?

我认为那里必须有一个 for...循环来遍历数组,但我还没有找到创建嵌套对象的方法。

如果您已经走到了这一步,非常感谢您抽出时间阅读,即使您无能为力。

【问题讨论】:

    标签: javascript arrays object dynamic nested


    【解决方案1】:

    放入一个函数,短而快(无递归)。

    var createNestedObject = function( base, names ) {
        for( var i = 0; i < names.length; i++ ) {
            base = base[ names[i] ] = base[ names[i] ] || {};
        }
    };
    
    // Usage:
    createNestedObject( window, ["shapes", "triangle", "points"] );
    // Now window.shapes.triangle.points is an empty object, ready to be used.
    

    它会跳过层次结构中已经存在的部分。如果您不确定层次结构是否已经创建,这很有用。

    或者:

    一个更高级的版本,您可以直接将值分配给层次结构中的最后一个对象,并且您可以链接函数调用,因为它返回最后一个对象。

    // Function: createNestedObject( base, names[, value] )
    //   base: the object on which to create the hierarchy
    //   names: an array of strings contaning the names of the objects
    //   value (optional): if given, will be the last object in the hierarchy
    // Returns: the last object in the hierarchy
    var createNestedObject = function( base, names, value ) {
        // If a value is given, remove the last name and keep it for later:
        var lastName = arguments.length === 3 ? names.pop() : false;
    
        // Walk the hierarchy, creating new objects where needed.
        // If the lastName was removed, then the last object is not set yet:
        for( var i = 0; i < names.length; i++ ) {
            base = base[ names[i] ] = base[ names[i] ] || {};
        }
    
        // If a value was given, set it to the last name:
        if( lastName ) base = base[ lastName ] = value;
    
        // Return the last object in the hierarchy:
        return base;
    };
    
    // Usages:
    
    createNestedObject( window, ["shapes", "circle"] );
    // Now window.shapes.circle is an empty object, ready to be used.
    
    var obj = {}; // Works with any object other that window too
    createNestedObject( obj, ["shapes", "rectangle", "width"], 300 );
    // Now we have: obj.shapes.rectangle.width === 300
    
    createNestedObject( obj, "shapes.rectangle.height".split('.'), 400 );
    // Now we have: obj.shapes.rectangle.height === 400
    

    注意:如果您的层次结构需要从标准对象以外的值构建(即不是 {}),另请参阅下面 TimDog 的答案。

    编辑:使用常规循环而不是 for...in 循环。在库修改 Array 原型的情况下会更安全。

    【讨论】:

    • 我希望您意识到您正在回答一个已被接受的答案已经超过 15 个月的问题...
    • 没关系,只是提出问题的人不太可能仍在寻找答案。您的回答仍然很好(并且与其他人不同),所以我给了您一些赞许。
    • 实际上,这是最好的答案,因为它的行为符合预期。
    • @jlgrall 如果我需要从另一个处理实际值分配的函数中调用它,有没有办法返回新的键路径而不是键的值(基)?
    • 改进现有答案永远不会太晚。
    【解决方案2】:
    function assign(obj, keyPath, value) {
       lastKeyIndex = keyPath.length-1;
       for (var i = 0; i < lastKeyIndex; ++ i) {
         key = keyPath[i];
         if (!(key in obj)){
           obj[key] = {}
         }
         obj = obj[key];
       }
       obj[keyPath[lastKeyIndex]] = value;
    }
    

    用法:

    var settings = {};
    assign(settings, ['Modules', 'Video', 'Plugin'], 'JWPlayer');
    

    【讨论】:

    • 好吧,我写的几乎一样,只是我要解释newSettingName.split('_')。我没有看到重复答案背后的意义,所以在那里。也许更好地解释你的答案。
    • 该函数中的 keyPath 和 value 到底是什么?
    • 伟大的。我确实达到了最后一个值,因此失败了。了解,搜索并找到了这个。处于父母级别是关键并且工作正常。
    • keyPath 这里为上面的例子,意思是,key是Modules.Video.Plugin,value是JWPlayer,在他们试图构建的json中
    【解决方案3】:

    我的 ES2015 解决方案。保留现有值。

    const set = (obj, path, val) => { 
        const keys = path.split('.');
        const lastKey = keys.pop();
        const lastObj = keys.reduce((obj, key) => 
            obj[key] = obj[key] || {}, 
            obj); 
        lastObj[lastKey] = val;
    };
    

    例子:

    const obj = {'a': {'prop': {'that': 'exists'}}};
    set(obj, 'a.very.deep.prop', 'value');
    console.log(JSON.stringify(obj));
    // {"a":{"prop":{"that":"exists"},"very":{"deep":{"prop":"value"}}}}
    

    【讨论】:

    • 这是完美而聪明的谢谢。
    【解决方案4】:

    使用 ES6 会缩短。将路径设置为数组。 首先,您必须反转数组,才能开始填充对象。

    let obj = ['a','b','c'] // {a:{b:{c:{}}}
    obj.reverse();
    
    const nestedObject = obj.reduce((prev, current) => (
        {[current]:{...prev}}
    ), {});
    

    【讨论】:

    • 太棒了!如果之前定义了 nestedObject 并且设置了 {a: {b:{}} ,但没有 a.b.c ,如何更改此设置。 ? IE。保留现有的密钥,只添加缺失的。那真的很有用。
    【解决方案5】:

    另一种递归解决方案:

    var nest = function(obj, keys, v) {
        if (keys.length === 1) {
          obj[keys[0]] = v;
        } else {
          var key = keys.shift();
          obj[key] = nest(typeof obj[key] === 'undefined' ? {} : obj[key], keys, v);
        }
    
        return obj;
    };
    

    示例用法:

    var dog = {bark: {sound: 'bark!'}};
    nest(dog, ['bark', 'loudness'], 66);
    nest(dog, ['woff', 'sound'], 'woff!');
    console.log(dog); // {bark: {loudness: 66, sound: "bark!"}, woff: {sound: "woff!"}}
    

    【讨论】:

      【解决方案6】:

      我喜欢这种在嵌套字段上设置特定值的 ES6 不可变方式:

      const setValueToField = (fields, value) => {
        const reducer = (acc, item, index, arr) => ({ [item]: index + 1 < arr.length ? acc : value });
        return fields.reduceRight(reducer, {});
      };
      

      然后用它来创建你的目标对象。

      const targetObject = setValueToField(['one', 'two', 'three'], 'nice');
      console.log(targetObject); // Output: { one: { two: { three: 'nice' } } }
      

      【讨论】:

      • 完美。谢谢你。
      • 对 ES6 的巧妙使用
      • 好,我们如何添加对象数组?示例 { 一:[ {} ,{} , {} ],二:[ {},{},{} ] }
      【解决方案7】:

      这是对 jlgrall 答案的简单调整,允许在嵌套层次结构中的每个元素上设置 distinct 值:

      var createNestedObject = function( base, names, values ) {
          for( var i in names ) base = base[ names[i] ] = base[ names[i] ] || (values[i] || {});
      };
      

      希望对你有帮助。

      【讨论】:

      • 为什么这会起作用而不是删除现有的嵌套对象?!先生,您大吃一惊。
      • 我知道这是旧的,但我想我会插话。这样做的原因是“base”参数是由对原始对象的引用的副本传递的。因此,在每次迭代中,从右到左计算的基数变成了指向当前分配属性位置的指针。
      【解决方案8】:

      这是一个动态创建嵌套对象的功能解决方案。

      const nest = (path, obj) => {
        const reversedPath = path.split('.').reverse();
      
        const iter = ([head, ...tail], obj) => {
          if (!head) {
            return obj;
          }
          const newObj = {[head]: {...obj}};
          return iter(tail, newObj);
        }
        return iter(reversedPath, obj);
      }
      

      例子:

      const data = {prop: 'someData'};
      const path = 'a.deep.path';
      const result = nest(path, data);
      console.log(JSON.stringify(result));
      // {"a":{"deep":{"path":{"prop":"someData"}}}}
      

      【讨论】:

        【解决方案9】:

        Lodash 有一个_.set 方法来实现这一点

        let obj = {}
        
        _.set(obj, ['a', 'b', 'c', 'd'], 'e')
        
        or
        
        _.set(obj, 'a.b.c.d', 'e')
        
        // which generate the following object
        {
           "a": {
              "b": {
                 "c": {
                    "d": "e"
                 }
              }
           }
        }
        

        【讨论】:

          【解决方案10】:

          灵感来自 ImmutableJS 的 setIn 方法,它永远不会改变原始的。这适用于混合数组和对象嵌套值。

          function setIn(obj = {}, [prop, ...rest], value) {
              const newObj = Array.isArray(obj) ? [...obj] : {...obj};
              newObj[prop] = rest.length ? setIn(obj[prop], rest, value) : value;
              return newObj;
          }
          
          var obj = {
            a: {
              b: {
                c: [
                  {d: 5}
                ]
              }
            }
          };
          
          const newObj = setIn(obj, ["a", "b", "c", 0, "x"], "new");
          
          //obj === {a: {b: {c: [{d: 5}]}}}
          //newObj === {a: {b: {c: [{d: 5, x: "new"}]}}}
          

          【讨论】:

            【解决方案11】:

            感谢这个问题太老了!但是在遇到需要在 node 中做这样的事情之后,我制作了一个模块并将其发布到 npm。 Nestob

            var nestob = require('nestob');
            
            //Create a new nestable object - instead of the standard js object ({})
            var newNested = new nestob.Nestable();
            
            //Set nested object properties without having to create the objects first!
            newNested.setNested('biscuits.oblong.marmaduke', 'cheese');
            newNested.setNested(['orange', 'tartan', 'pipedream'], { poppers: 'astray', numbers: [123,456,789]});
            
            console.log(newNested, newNested.orange.tartan.pipedream);
            //{ biscuits: { oblong: { marmaduke: 'cheese' } },
              orange: { tartan: { pipedream: [Object] } } } { poppers: 'astray', numbers: [ 123, 456, 789 ] }
            
            //Get nested object properties without having to worry about whether the objects exist
            //Pass in a default value to be returned if desired
            console.log(newNested.getNested('generic.yoghurt.asguard', 'autodrome'));
            //autodrome
            
            //You can also pass in an array containing the object keys
            console.log(newNested.getNested(['chosp', 'umbridge', 'dollar'], 'symbols'));
            //symbols
            
            //You can also use nestob to modify objects not created using nestob
            var normalObj = {};
            
            nestob.setNested(normalObj, 'running.out.of', 'words');
            
            console.log(normalObj);
            //{ running: { out: { of: 'words' } } }
            
            console.log(nestob.getNested(normalObj, 'random.things', 'indigo'));
            //indigo
            console.log(nestob.getNested(normalObj, 'improbable.apricots'));
            //false
            

            【讨论】:

              【解决方案12】:

              在您的循环中,您可以使用 lodash.set 并为您创建路径:

              ...
              const set = require('lodash.set');
              
              const p = {};
              const [type, lang, name] = f.split('.');
              set(p, [lang, type, name], '');
              
              console.log(p);
              // { lang: { 'type': { 'name': '' }}}
              

              【讨论】:

                【解决方案13】:

                尝试使用递归函数:

                function createSetting(setting, value, index) {
                  if (typeof index !== 'number') {
                    index = 0;
                  }
                
                  if (index+1 == setting.length ) {
                    settings[setting[index]] = value;
                  }
                  else {
                    settings[setting[index]] = {};
                    createSetting(setting, value, ++index);
                  }
                }
                

                【讨论】:

                  【解决方案14】:

                  我认为,这更短:

                  Settings = {};
                  newSettingName = "Modules_Floorplan_Image_Src";
                  newSettingValue = "JWPlayer";
                  newSettingNameArray = newSettingName.split("_");
                  
                  a = Settings;
                  for (var i = 0 in newSettingNameArray) {
                      var x = newSettingNameArray[i];
                      a[x] = i == newSettingNameArray.length-1 ? newSettingValue : {};
                      a = a[x];
                  }
                  

                  【讨论】:

                    【解决方案15】:

                    我发现@jlgrall 的答案很棒,但在简化后,它在 Chrome 中不起作用。如果有人想要精简版,这是我的固定:

                    var callback = 'fn.item1.item2.callbackfunction',
                        cb = callback.split('.'),
                        baseObj = window;
                    
                    function createNestedObject(base, items){
                        $.each(items, function(i, v){
                            base = base[v] = (base[v] || {});
                        });
                    }
                    
                    callbackFunction = createNestedObject(baseObj, cb);
                    
                    console.log(callbackFunction);
                    

                    我希望这是有用且相关的。抱歉,我刚刚打破了这个例子......

                    【讨论】:

                      【解决方案16】:

                      您可以定义自己的 Object 方法;为了简洁起见,我也使用下划线:

                      var _ = require('underscore');
                      
                      // a fast get method for object, by specifying an address with depth
                      Object.prototype.pick = function(addr) {
                          if (!_.isArray(addr)) return this[addr]; // if isn't array, just get normally
                          var tmpo = this;
                          while (i = addr.shift())
                              tmpo = tmpo[i];
                          return tmpo;
                      };
                      // a fast set method for object, put value at obj[addr]
                      Object.prototype.put = function(addr, val) {
                          if (!_.isArray(addr)) this[addr] = val; // if isn't array, just set normally
                          this.pick(_.initial(addr))[_.last(addr)] = val;
                      };
                      

                      示例用法:

                      var obj = { 
                                 'foo': {
                                         'bar': 0 }}
                      
                      obj.pick('foo'); // returns { bar: 0 }
                      obj.pick(['foo','bar']); // returns 0
                      obj.put(['foo', 'bar'], -1) // obj becomes {'foo': {'bar': -1}}
                      

                      【讨论】:

                        【解决方案17】:

                        sn-p 适用于那些需要创建嵌套对象并支持数组键以将值设置到路径末尾的人。路径是这样的字符串:modal.product.action.review.2.write.survey.data。基于 jlgrall 版本。

                        var updateStateQuery = function(state, path, value) {
                            var names = path.split('.');
                            for (var i = 0, len = names.length; i < len; i++) {
                                if (i == (len - 1)) {
                                    state = state[names[i]] = state[names[i]] || value;
                                }
                                else if (parseInt(names[i+1]) >= 0) {
                                    state = state[names[i]] = state[names[i]] || [];
                                }
                                else {
                                    state = state[names[i]] = state[names[i]] || {};
                                }
                            }
                        };
                        

                        【讨论】:

                          【解决方案18】:

                          设置嵌套数据:

                          function setNestedData(root, path, value) {
                            var paths = path.split('.');
                            var last_index = paths.length - 1;
                            paths.forEach(function(key, index) {
                              if (!(key in root)) root[key] = {};
                              if (index==last_index) root[key] = value;
                              root = root[key];
                            });
                            return root;
                          }
                          
                          var obj = {'existing': 'value'};
                          setNestedData(obj, 'animal.fish.pet', 'derp');
                          setNestedData(obj, 'animal.cat.pet', 'musubi');
                          console.log(JSON.stringify(obj));
                          // {"existing":"value","animal":{"fish":{"pet":"derp"},"cat":{"pet":"musubi"}}}
                          

                          获取嵌套数据:

                          function getNestedData(obj, path) {
                            var index = function(obj, i) { return obj && obj[i]; };
                            return path.split('.').reduce(index, obj);
                          }
                          getNestedData(obj, 'animal.cat.pet')
                          // "musubi"
                          getNestedData(obj, 'animal.dog.pet')
                          // undefined
                          

                          【讨论】:

                            【解决方案19】:

                            Eval 可能有点矫枉过正,但结果很容易可视化,没有嵌套循环或递归。

                             function buildDir(obj, path){
                               var paths = path.split('_');
                               var final = paths.pop();
                               for (let i = 1; i <= paths.length; i++) {
                                 var key = "obj['" + paths.slice(0, i).join("']['") + "']"
                                 console.log(key)
                                 eval(`${key} = {}`)
                               }
                               eval(`${key} = '${final}'`)
                               return obj
                             }
                            
                             var newSettingName = "Modules_Video_Plugin_JWPlayer";
                             var Settings = buildDir( {}, newSettingName );
                            

                            基本上,您正在逐步编写字符串"obj['one']= {}", "obj['one']['two']"= {} 并对其进行评估;

                            【讨论】:

                              【解决方案20】:

                              试试这个:https://github.com/silkyland/object-to-formdata

                              var obj2fd = require('obj2fd/es5').default
                              var fd = obj2fd({
                                           a:1,
                                           b:[
                                              {c: 3},
                                              {d: 4}
                                           ]
                              })
                              

                              结果:

                              fd = [
                                     a => 1,
                                     b => [
                                       c => 3,
                                       d => 4
                                     ]
                              ]
                              

                              【讨论】:

                                【解决方案21】:

                                这里分解了几个有用的函数,每个函数都保留现有数据。不处理数组。

                                • setDeep:回答问题。不会破坏对象中的其他数据。
                                • setDefaultDeep:相同,但仅在尚未设置的情况下设置。
                                • setDefault:如果尚未设置,则设置密钥。与 Python 的 setdefault 相同。
                                • setStructure:构建路径的辅助函数。

                                // Create a nested structure of objects along path within obj. Only overwrites the final value.
                                let setDeep = (obj, path, value) =>
                                    setStructure(obj, path.slice(0, -1))[path[path.length - 1]] = value
                                
                                // Create a nested structure of objects along path within obj. Does not overwrite any value.
                                let setDefaultDeep = (obj, path, value) =>
                                    setDefault(setStructure(obj, path.slice(0, -1)), path[path.length - 1], value)
                                
                                // Set obj[key] to value if key is not in object, and return obj[key]
                                let setDefault = (obj, key, value) =>
                                    obj[key] = key in obj ? obj[key] : value;
                                
                                // Create a nested structure of objects along path within obj. Does not overwrite any value.
                                let setStructure = (obj, path) => 
                                    path.reduce((obj, segment) => setDefault(obj, segment, {}), obj);
                                
                                
                                
                                // EXAMPLES
                                let temp = {};
                                
                                // returns the set value, similar to assignment
                                console.log('temp.a.b.c.d:', 
                                            setDeep(temp, ['a', 'b', 'c', 'd'], 'one'))
                                
                                // not destructive to 'one'
                                setDeep(temp, ['a', 'b', 'z'], 'two')
                                
                                // does not overwrite, returns previously set value
                                console.log('temp.a.b.z:  ', 
                                            setDefaultDeep(temp, ['a', 'b', 'z'], 'unused'))
                                
                                // creates new, returns current value
                                console.log('temp["a.1"]: ', 
                                            setDefault(temp, 'a.1', 'three'))
                                
                                // can also be used as a getter
                                console.log("temp.x.y.z:  ", 
                                            setStructure(temp, ['x', 'y', 'z']))
                                
                                
                                console.log("final object:", temp)

                                我不确定为什么有人会想要字符串路径:

                                1. 它们对于带句点的键不明确
                                2. 您必须首先构建字符串

                                【讨论】:

                                  【解决方案22】:

                                  因为我从这个页面开始,我想回馈

                                  即使设置了最终节点,其他示例也会覆盖最终节点,这不是我想要的。

                                  另外,如果returnObj 设置为true,它会返回基础对象。默认情况下,falsy,它返回最深的节点。

                                  function param(obj, path, value, returnObj) {
                                    if (typeof path == 'string') path = path.split(".");
                                    var child = obj;
                                    path.forEach((key, i) => {
                                      if (!(key in child)) {
                                        child[key] = (i < path.length-1) ? {} : value || {};
                                      }
                                      child = child[key];
                                    });
                                    return returnObj ? obj : child;
                                  }
                                  
                                  var x = {};
                                  var xOut = param(x, "y.z", "setting")
                                  console.log(xOut);
                                  xOut = param(x, "y.z", "overwrite") // won't set
                                  console.log(xOut);
                                  xOut = param(x, "y.a", "setting2")
                                  console.log(xOut);
                                  xOut = param(x, "y.a", "setting2", true) // get object rather than deepest node.
                                  console.log(xOut);

                                  您还可以在数组中放置数字键(如果它们不存在)。请注意,数字键不会转换为路径的第一个元素的数组,因为它是由基础对象的类型设置的。

                                  function isNumber(n) {
                                    return !isNaN(parseFloat(n)) && isFinite(n);
                                  }
                                  
                                  function param(obj, path, value, returnObj) {
                                    if (typeof path == 'string') path = path.split(".");
                                    var child = obj;
                                    path.forEach((key, i) => {
                                      var nextKey = path[i+1];
                                      if (!(key in child)) {
                                        child[key] = (nextKey == undefined && value != undefined 
                                          ? value 
                                          : isNumber(nextKey)
                                            ? []
                                            : {});
                                      }
                                      child = child[key];
                                    });
                                    return returnObj ? obj : child;
                                  }
                                  
                                  var x = {};
                                  
                                  var xOut = param(x, "y.z", "setting")
                                  console.log(xOut);
                                  xOut = param(x, "y.z", "overwrite") // won't set
                                  console.log(xOut);
                                  xOut = param(x, "y.a", "setting2")
                                  console.log(xOut);
                                  xOut = param(x, "y.a", "setting2", true) // get object rather than deepest node.
                                  xOut = param(x, "1.0.2.a", "setting")
                                  xOut = param(x, "1.0.1.a", "try to override") // won't set
                                  xOut = param(x, "1.0.5.a", "new-setting", true) // get object rather than deepest node.
                                  console.log(xOut);

                                  当然,当数字键大于 0 时,您可能会看到一些 undefined 空白。

                                  这个的实际用途可能是

                                  function AddNote(book, page, line) {
                                    // assume a global global notes collection
                                    var myNotes = param(allNotes, [book, page, line], []);
                                    myNotes.push('This was a great twist!')
                                    return myNotes;
                                  }
                                  
                                  var allNotes = {}
                                  var youthfulHopes = AddNote('A Game of Thrones', 4, 2, "I'm already hooked, at least I won't have to wait long for the books to come out!");
                                  
                                  console.log(allNotes)
                                  // {"A Game of Thrones": [undefined, undefined, undefined, undefined, [undefined, undefined, ["I'm already hooked, at least I won't have to wait long for the books to come out!"]]]}
                                  console.log(youthfulHopes)
                                  // ["I'm already hooked, at least I won't have to wait long for the books to come out!"]
                                  

                                  【讨论】:

                                    【解决方案23】:
                                    function initPath(obj, path) {
                                      path.split('.').reduce((o, key) => (
                                        Object.assign(o, {[key]: Object(o[key])}),
                                        o[key]
                                      ), obj);
                                      return obj;
                                    }
                                    

                                    用法

                                    const obj = { a: { b: 'value1' } };
                                    initPath(obj, 'a.c.d').a.c.d='value2';
                                    /*
                                    {
                                      "a": {
                                        "b": "value1",
                                        "c": {
                                          "d": "value2"
                                        }
                                      }
                                    }
                                    */
                                    

                                    【讨论】:

                                      【解决方案24】:

                                      简单的答案。在 es6 上,我正在使用这个

                                      const assign = (obj, path, value) => {
                                        let keyPath = path.split('.')
                                        let lastKeyIndex = keyPath.length - 1
                                        for (let i = 0; i < lastKeyIndex; ++i) {
                                          let key = keyPath[i]
                                          if (!(key in obj)) {
                                            obj[key] = {}
                                          }
                                          obj = obj[key]
                                        }
                                        obj[keyPath[lastKeyIndex]] = value
                                      }
                                      

                                      示例 json

                                      const obj = {
                                        b: 'hello'
                                      }
                                      

                                      您可以添加新密钥

                                      assign(obj, 'c.d.e', 'this value')
                                      

                                      你会像下面这样

                                      console.log(obj)
                                      //response example
                                      obj = {
                                         b: 'hello',
                                         c: {
                                            d: {
                                               e: 'this value'
                                            }
                                         }
                                      }
                                      

                                      【讨论】:

                                        【解决方案25】:

                                        function createObj(keys, value) {
                                            let obj = {}
                                          let schema = obj
                                            keys = keys.split('.')
                                          
                                          for (let i = 0; i < keys.length - 1; i++) {
                                            schema[keys[i]] = {}
                                            schema = schema[keys[i]]
                                          }
                                          
                                          schema[keys.pop()] = value
                                        
                                            return obj
                                        }
                                        
                                        
                                        let keys = 'value1.value2.value3'
                                        let value = 'Hello'
                                        
                                        let obj = createObj(keys, value)

                                        【讨论】:

                                        • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
                                        猜你喜欢
                                        • 2015-10-18
                                        • 1970-01-01
                                        • 1970-01-01
                                        • 2016-09-04
                                        • 2021-03-31
                                        • 2021-08-02
                                        • 1970-01-01
                                        • 1970-01-01
                                        • 1970-01-01
                                        相关资源
                                        最近更新 更多