Convert JavaScript string in dot notation into an object reference

前端 未结 27 3005
梦如初夏
梦如初夏 2020-11-21 05:09

Given a JS object

var obj = { a: { b: \'1\', c: \'2\' } }

and a string

\"a.b\"

how can I convert the stri

相关标签:
27条回答
  • 2020-11-21 05:46

    Here is my implementation

    Implementation 1

    Object.prototype.access = function() {
        var ele = this[arguments[0]];
        if(arguments.length === 1) return ele;
        return ele.access.apply(ele, [].slice.call(arguments, 1));
    }
    

    Implementation 2 (using array reduce instead of slice)

    Object.prototype.access = function() {
        var self = this;
        return [].reduce.call(arguments,function(prev,cur) {
            return prev[cur];
        }, self);
    }
    

    Examples:

    var myobj = {'a':{'b':{'c':{'d':'abcd','e':[11,22,33]}}}};
    
    myobj.access('a','b','c'); // returns: {'d':'abcd', e:[0,1,2,3]}
    myobj.a.b.access('c','d'); // returns: 'abcd'
    myobj.access('a','b','c','e',0); // returns: 11
    

    it can also handle objects inside arrays as for

    var myobj2 = {'a': {'b':[{'c':'ab0c'},{'d':'ab1d'}]}}
    myobj2.access('a','b','1','d'); // returns: 'ab1d'
    
    0 讨论(0)
  • 2020-11-21 05:47

    I suggest to split the path and iterate it and reduce the object you have. This proposal works with a default value for missing properties.

    const getValue = (object, keys) => keys.split('.').reduce((o, k) => (o || {})[k], object);
    
    console.log(getValue({ a: { b: '1', c: '2' } }, 'a.b'));
    console.log(getValue({ a: { b: '1', c: '2' } }, 'foo.bar.baz'));

    0 讨论(0)
  • 2020-11-21 05:47

    You can use the library available at npm, which simplifies this process. https://www.npmjs.com/package/dot-object

     var dot = require('dot-object');
    
    var obj = {
     some: {
       nested: {
         value: 'Hi there!'
       }
     }
    };
    
    var val = dot.pick('some.nested.value', obj);
    console.log(val);
    
    // Result: Hi there!
    
    0 讨论(0)
  • 2020-11-21 05:50

    If you can use lodash, there is a function, which does exactly that:

    _.get(object, path, [defaultValue])

    var val = _.get(obj, "a.b");
    
    0 讨论(0)
  • 2020-11-21 05:52
    var find = function(root, path) {
      var segments = path.split('.'),
          cursor = root,
          target;
    
      for (var i = 0; i < segments.length; ++i) {
       target = cursor[segments[i]];
       if (typeof target == "undefined") return void 0;
       cursor = target;
      }
    
      return cursor;
    };
    
    var obj = { a: { b: '1', c: '2' } }
    find(obj, "a.b"); // 1
    
    var set = function (root, path, value) {
       var segments = path.split('.'),
           cursor = root,
           target;
    
       for (var i = 0; i < segments.length - 1; ++i) {
          cursor = cursor[segments[i]] || { };
       }
    
       cursor[segments[segments.length - 1]] = value;
    };
    
    set(obj, "a.k", function () { console.log("hello world"); });
    
    find(obj, "a.k")(); // hello world
    
    0 讨论(0)
  • 2020-11-21 05:52

    I copied the following from Ricardo Tomasi's answer and modified to also create sub-objects that don't yet exist as necessary. It's a little less efficient (more ifs and creating of empty objects), but should be pretty good.

    Also, it'll allow us to do Object.prop(obj, 'a.b', false) where we couldn't before. Unfortunately, it still won't let us assign undefined...Not sure how to go about that one yet.

    /**
     * Object.prop()
     *
     * Allows dot-notation access to object properties for both getting and setting.
     *
     * @param {Object} obj    The object we're getting from or setting
     * @param {string} prop   The dot-notated string defining the property location
     * @param {mixed}  val    For setting only; the value to set
     */
     Object.prop = function(obj, prop, val){
       var props = prop.split('.'),
           final = props.pop(),
           p;
    
       for (var i = 0; i < props.length; i++) {
         p = props[i];
         if (typeof obj[p] === 'undefined') {
           // If we're setting
           if (typeof val !== 'undefined') {
             // If we're not at the end of the props, keep adding new empty objects
             if (i != props.length)
               obj[p] = {};
           }
           else
             return undefined;
         }
         obj = obj[p]
       }
       return typeof val !== "undefined" ? (obj[final] = val) : obj[final]
     }
    
    0 讨论(0)
提交回复
热议问题