我有一个这样的数据结构:

var someObject = {
    'part1' : {
        'name': 'Part 1',
        'size': '20',
        'qty' : '50'
    },
    'part2' : {
        'name': 'Part 2',
        'size': '15',
        'qty' : '60'
    },
    'part3' : [
        {
            'name': 'Part 3A',
            'size': '10',
            'qty' : '20'
        }, {
            'name': 'Part 3B',
            'size': '5',
            'qty' : '20'
        }, {
            'name': 'Part 3C',
            'size': '7.5',
            'qty' : '20'
        }
    ]
};

我想使用这些变量访问数据:

var part1name = "part1.name";
var part2quantity = "part2.qty";
var part3name1 = "part3[0].name";

part1name应该用someObject.part1.name的值填充,即“Part 1”。part2quantity也是一样,它的容量是60。

有没有办法实现这与纯javascript或JQuery?


当前回答

mohamed Hamouday' Answer的扩展将填补缺失的关键

function Object_Manager(obj, Path, value, Action, strict) 
{
    try
    {
        if(Array.isArray(Path) == false)
        {
            Path = [Path];
        }

        let level = 0;
        var Return_Value;
        Path.reduce((a, b)=>{
            console.log(level,':',a, '|||',b)
            if (!strict){
              if (!(b in a)) a[b] = {}
            }


            level++;
            if (level === Path.length)
            {
                if(Action === 'Set')
                {
                    a[b] = value;
                    return value;
                }
                else if(Action === 'Get')
                {
                    Return_Value = a[b];
                }
                else if(Action === 'Unset')
                {
                    delete a[b];
                }
            } 
            else 
            {
                return a[b];
            }
        }, obj);
        return Return_Value;
    }

    catch(err)
    {
        console.error(err);
        return obj;
    }
}

例子


obja = {
  "a": {
    "b":"nom"
  }
}

// Set
path = "c.b" // Path does not exist
Object_Manager(obja,path.split('.'), 'test_new_val', 'Set', false);

// Expected Output: Object { a: Object { b: "nom" }, c: Object { b: "test_new_value" } }

其他回答

现在lodash使用_支持这一点。get (obj,财产)。看到https://lodash.com/docs

文档中的例子:

var object = { 'a': [{ 'b': { 'c': 3 } }] };

_.get(object, 'a[0].b.c');
// → 3

_.get(object, ['a', '0', 'b', 'c']);
// → 3

_.get(object, 'a.b.c', 'default');
// → 'default'

// (IE9+) Two steps var pathString = "[0]['property'].others[3].next['final']"; var obj = [{ property: { others: [1, 2, 3, { next: { final: "SUCCESS" } }] } }]; // Turn string to path array var pathArray = pathString .replace(/\[["']?([\w]+)["']?\]/g,".$1") .split(".") .splice(1); // Add object prototype method Object.prototype.path = function (path) { try { return [this].concat(path).reduce(function (f, l) { return f[l]; }); } catch (e) { console.error(e); } }; // usage console.log(obj.path(pathArray)); console.log(obj.path([0,"doesNotExist"]));

我的解决方案是基于@AdrianoSpadoni给出的,并解决了克隆对象的需要

function generateData(object: any, path: string, value: any): object {
  const clone = JSON.parse(JSON.stringify(object));
  path
    .split(".")
    .reduce(
    (o, p, i) => (o[p] = path.split(".").length === ++i ? value : o[p] || {}),
  clone
);
  return clone;
}

如果您想要一个能够正确检测和报告路径解析的任何问题的详细信息的解决方案,我为此编写了自己的解决方案——库路径-值。

const {resolveValue} = require('path-value');

resolveValue(someObject, 'part1.name'); //=> Part 1
resolveValue(someObject, 'part2.qty'); //=> 50
resolveValue(someObject, 'part3.0.name'); //=> Part 3A

请注意,对于索引,我们使用.0,而不是[0],因为解析后者会增加性能损失,而.0直接在JavaScript中工作,因此非常快。

然而,完整的ES5 JavaScript语法也被支持,它只需要首先被标记化:

const {resolveValue, tokenizePath} = require('path-value');

const path = tokenizePath('part3[0].name'); //=> ['part3', '0', 'name']

resolveValue(someObject, path); //=> Part 3A

你可以使用ramda库。

学习ramda还可以帮助您轻松地使用不可变对象。


var obj = {
  a:{
    b: {
      c:[100,101,{
        d: 1000
      }]
    }
  }
};


var lens = R.lensPath('a.b.c.2.d'.split('.'));
var result = R.view(lens, obj);


https://codepen.io/ghominejad/pen/BayJZOQ