我有一个这样的数据结构:
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?
最近遇到了同样的问题,并且成功地使用了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
受到@webjay的回答的启发:
https://stackoverflow.com/a/46008856/4110122
我做了这个函数,你可以用它来获取/设置/取消设置对象中的任何值
function Object_Manager(obj, Path, value, Action)
{
try
{
if(Array.isArray(Path) == false)
{
Path = [Path];
}
let level = 0;
var Return_Value;
Path.reduce((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;
}
}
使用它:
// Set
Object_Manager(Obj,[Level1,Level2,Level3],New_Value, 'Set');
// Get
Object_Manager(Obj,[Level1,Level2,Level3],'', 'Get');
// Unset
Object_Manager(Obj,[Level1,Level2,Level3],'', 'Unset');
这可能永远都不会曝光……但不管怎样,它在这里。
将[]括号语法替换为。
继续前进。字符
删除空白字符串
找到路径(否则未定义)
(为了找到一个对象的路径,使用这个pathTo解决方案。)
// "one liner" (ES6)
const deep_value = (obj, path) =>
path
.replace(/\[|\]\.?/g, '.')
.split('.')
.filter(s => s)
.reduce((acc, val) => acc && acc[val], obj);
// ... and that's it.
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'
}
// ...
],
'pa[rt3' : [
{
'name': 'Part 3A',
'size': '10',
'qty' : '20'
}
// ...
]
};
console.log(deep_value(someObject, "part1.name")); // Part 1
console.log(deep_value(someObject, "part2.qty")); // 60
console.log(deep_value(someObject, "part3[0].name")); // Part 3A
console.log(deep_value(someObject, "part3[0].....name")); // Part 3A - invalid blank paths removed
console.log(deep_value(someObject, "pa[rt3[0].name")); // undefined - name does not support square brackets
你可以通过以下简单的技巧,在没有任何外部JavaScript库的情况下,使用点表示法获得deep对象成员的值:
function objectGet(obj, path) { return new Function('_', 'return _.' + path)(obj); };
在你的例子中,要从someObject中获取part1.name的值,只需做:
objectGet(someObject, 'part1.name');
这里是一个简单的小提琴演示:https://jsfiddle.net/harishanchu/oq5esowf/
使用对象扫描,这就变成了一行。然而,更重要的是,这个解决方案考虑性能:
在搜索期间遍历一次输入(即使查询了多个键)
解析只在init上发生一次(如果查询多个对象)
允许使用*进行扩展语法
// const objectScan = require('object-scan');
const 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' }] };
const get = (haystack, needle) => objectScan([needle], { rtn: 'value', abort: true })(haystack);
console.log(get(someObject, 'part1.name'));
// => Part 1
console.log(get(someObject, 'part2.qty'));
// => 60
console.log(get(someObject, 'part3[0].name'));
// => Part 3A
const getAll = (haystack, ...needles) => objectScan(needles, { reverse: false, rtn: 'entry', joined: true })(haystack);
console.log(getAll(someObject, 'part1.name', 'part2.qty', 'part3[0].name'));
/* =>
[ [ 'part1.name', 'Part 1' ],
[ 'part2.qty', '60' ],
[ 'part3[0].name', 'Part 3A' ] ]
*/
console.log(getAll(someObject, 'part1.*'));
/* =>
[ [ 'part1.name', 'Part 1' ],
[ 'part1.size', '20' ],
[ 'part1.qty', '50' ] ]
*/
.as-console-wrapper {max-height: 100% !important; top: 0}
<script src="https://bundle.run/object-scan@13.8.0"></script>
声明:我是object-scan的作者