给定一个JavaScript对象,
var obj = { a: { b: '1', c: '2' } }
和字符串
"a.b"
我怎么把字符串转换成点符号呢
var val = obj.a.b
如果字符串只是'a',我可以使用obj[a]。但这个更复杂。我想应该有什么简单的方法,但现在想不起来了。
给定一个JavaScript对象,
var obj = { a: { b: '1', c: '2' } }
和字符串
"a.b"
我怎么把字符串转换成点符号呢
var val = obj.a.b
如果字符串只是'a',我可以使用obj[a]。但这个更复杂。我想应该有什么简单的方法,但现在想不起来了。
当前回答
我在我的项目中使用了这个代码
const getValue = (obj, arrPath) => (
arrPath.reduce((x, y) => {
if (y in x) return x[y]
return {}
}, obj)
)
用法:
const obj = { id: { user: { local: 104 } } }
const path = [ 'id', 'user', 'local' ]
getValue(obj, path) // return 104
其他回答
这是我的实现
实现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));
}
实现2(使用数组reduce而不是slice)
Object.prototype.access = function() {
var self = this;
return [].reduce.call(arguments,function(prev,cur) {
return prev[cur];
}, self);
}
例子:
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
它也可以处理数组中的对象
var myobj2 = {'a': {'b':[{'c':'ab0c'},{'d':'ab1d'}]}}
myobj2.access('a','b','1','d'); // returns: 'ab1d'
这是一个递归的例子。
函数重组(obj,字符串){ Var parts = string.split('.'); var newObj = obj[parts[0]]; If (parts[1]) { 部分。拼接(0,1); var newString = parts.join('.'); return recompose(newObj, newString); } 返回newObj; } var obj ={答:{' 1 ',c:‘2’,d:{答:{b:“胡说”}}}}; console.log(重组(obj, ' a.d.a.b '));/ /等等
function at(obj, path, val = undefined) { // If path is an Array, if (Array.isArray(path)) { // it returns the mapped array for each result of the path return path.map((path) => at(obj, path, val)); } // Uniting several RegExps into one const rx = new RegExp( [ /(?:^(?:\.\s*)?([_a-zA-Z][_a-zA-Z0-9]*))/, /(?:^\[\s*(\d+)\s*\])/, /(?:^\[\s*'([^']*(?:\\'[^']*)*)'\s*\])/, /(?:^\[\s*"([^"]*(?:\\"[^"]*)*)"\s*\])/, /(?:^\[\s*`([^`]*(?:\\`[^`]*)*)`\s*\])/, ] .map((r) => r.source) .join("|") ); let rm; while (rm = rx.exec(path.trim())) { // Matched resource let [rf, rp] = rm.filter(Boolean); // If no one matches found, if (!rm[1] && !rm[2]) { // it will replace escape-chars rp = rp.replace(/\\(.)/g, "$1"); } // If the new value is set, if ("undefined" != typeof val && path.length == rf.length) { // assign a value to the object property and return it return (obj[rp] = val); } // Going one step deeper obj = obj[rp]; // Removing a step from the path path = path.substr(rf.length).trim(); } if (path) { throw new SyntaxError(); } return obj; } // Test object schema let o = { a: { b: [ [ { c: { d: { '"e"': { f: { g: "xxx" } } } } } ] ] } }; // Print source object console.log(JSON.stringify(o)); // Set value console.log(at(o, '.a["b"][0][0].c[`d`]["\\"e\\""][\'f\']["g"]', "zzz")); // Get value console.log(at(o, '.a["b"][0][0].c[`d`]["\\"e\\""][\'f\']["g"]')); // Print result object console.log(JSON.stringify(o));
如果您希望以尽可能快的方式做到这一点,同时处理与路径解析或属性解析有关的任何问题,请检查path-value。
const {resolveValue} = require('path-value');
const value = resolveValue(obj, 'a.b.c');
该库是100%的TypeScript,适用于NodeJS +所有web浏览器。它是完全可扩展的,你可以使用较低级别的resolvePath,如果你愿意,你可以用自己的方式处理错误。
const {resolvePath} = require('path-value');
const res = resolvePath(obj, 'a.b.c'); //=> low-level parsing result descriptor
var a = { b: { c: 9 } };
function value(layer, path, value) {
var i = 0,
path = path.split('.');
for (; i < path.length; i++)
if (value != null && i + 1 === path.length)
layer[path[i]] = value;
layer = layer[path[i]];
return layer;
};
value(a, 'b.c'); // 9
value(a, 'b.c', 4);
value(a, 'b.c'); // 4
与简单得多的eval相比,这是一大堆代码,但就像Simon Willison说的,你永远不应该使用eval。
另外,JSFiddle。