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

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?


当前回答

现在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'

其他回答

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" } }

我认为你的要求是:

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

你可以这样问:

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

这两种方法都可行


也许这是你自找的

var partName = "part1";
var nameStr = "name";

var part1name = someObject[partName][nameStr];

终于轮到你自找麻烦了

var partName = "part1.name";

var partBits = partName.split(".");

var part1name = someObject[partBits[0]][partBits[1]];

根据阿尔尼塔克的回答。

我把填充材料包在格子里,将函数简化为单链还原。

如果对象。byPath === undefined) { 对象。byPath = (obj, path) =>路径 .replace (/ \ [(\ w +) \] / g, 1美元。) .replace(/ ^ \。/”) .split (/ \ / g)。 .reduce((ref, key) => key in ref ?Ref [key]: Ref, obj) } Const data = { foo: { 酒吧:[{ 记者:1 }) } } console.log(对象。小路(数据,foo.bar [0] .baz '))

这可以通过将逻辑分解为三个独立的函数来简化:

const isVal = a => a != null; // everything except undefined + null

const prop = prop => obj => {
    if (isVal(obj)) {
        const value = obj[prop];
        if (isVal(value)) return value;
        else return undefined;
    } else return undefined;
};

const path = paths => obj => {
    const pathList = typeof paths === 'string' ? paths.split('.') : paths;
    return pathList.reduce((value, key) => prop(key)(value), obj);
};

//usage:
const myObject = { foo: { bar: { baz: 'taco' } } };
const result = path('foo.bar')(myObject);
//results => { baz: 'taco' }

这个变体支持:

传递一个数组或字符串参数 在调用和执行期间处理未定义的值 独立测试每个功能 单独使用每个函数

最近遇到了同样的问题,并且成功地使用了https://npmjs.org/package/tea-properties,它也设置了嵌套对象/数组:

get:

var o = {
  prop: {
    arr: [
      {foo: 'bar'}
    ]
  }
};

var properties = require('tea-properties');
var value = properties.get(o, 'prop.arr[0].foo');

assert(value, 'bar'); // true

set:

var o = {};

var properties = require('tea-properties');
properties.set(o, 'prop.arr[0].foo', 'bar');

assert(o.prop.arr[0].foo, 'bar'); // true