getPathValue() 函数用于具有数组和打包 JSON 的深层对象
getPathValue() function for deep objects with arrays and with packed JSON
背景可以参考这个问题:
那里提供的解决方案与键值中包含的打包 JSON 配合得很好。
但是,他们不处理 JSON 有数组的情况。
我在另一个问题中引用的原始函数 DID 处理数组,但它不会处理打包的 JSON。
这是原始函数:
function getPathValue(obj, path) {
return new Function('_', 'return _.' + path)(obj);
}
这是第一个问题的答案:
function getValue(object, path) {
return path
.split('.')
.reduce((o, k) => (typeof o === 'string' ? JSON.parse(o) : o)[k],
object);
}
同样,两者都很好用,但都没有提供完整的服务包。
我需要一个可以同时完成这两个任务的解决方案,并且它必须在 IE11 的 ES5 中运行。
这是一个示例 API 返回 JSON 字符串:
{"id":"0001","type":"donut","name":"Cake","ppu":0.55,"batters":{"batter":[{"id":"1001","type":"Regular"},{"id":"1002","type":"Chocolate"}]},"data":"{\"domain\":\"cooking.com\",\"id\":53819390}"}
我希望能够使用路径字符串查询值,例如:
value = getPathValue(obj, 'batters.batter[2].id');
或
value = getPathValue(obj, 'type');
或
value = getPathValue(obj, 'data.domain');
您可以替换括号并将剩余的值作为键。在减少内部,您可以为未给定的对象使用默认对象。
function getValue(object, path) {
return path
.replace(/\[/g, '.')
.replace(/\]/g, '')
.split('.')
.reduce(function (o, k) {
return (typeof o === 'string' ? JSON.parse(o) : (o || {}))[k];
}, object);
}
var object = {"id":"0001","type":"donut","name":"Cake","ppu":0.55,"batters":{"batter":[{"id":"1001","type":"Regular"},{"id":"1002","type":"Chocolate"}]},"data":"{\"domain\":\"cooking.com\",\"id\":53819390}"},
path = 'batters.batter[1].id';
console.log(getValue(object, path));
以下将对每个值使用正则表达式来完成工作:
const data = {
"id": "0001",
"type": "donut",
"name": "Cake",
"ppu": 0.55,
"batters": {
"batter": [
{
"id": "1001",
"type": "Regular"
},
{
"id": "1002",
"type": "Chocolate"
}
]
},
"data": "{\"domain\":\"cooking.com\",\"id\":53819390}"
}
function getValue(object, path) {
return path
.split('.')
.reduce(function (o, k) {
const indexSearch = (new RegExp(/\[([0-9]*)\]/)).exec(k)
const index = indexSearch ? indexSearch[1] : null
k = k.replace(/\[[0-9]*\]/, '')
const sub = (typeof o === 'string' ? JSON.parse(o) : o)[k]
return index ? sub[index] : sub;
}, object);
}
console.log(getValue(data, 'batters.batter[1]'))
console.log(getValue(data, 'data.domain'))
console.log(getValue(data, 'batters.batter[1].id'))
背景可以参考这个问题:
那里提供的解决方案与键值中包含的打包 JSON 配合得很好。
但是,他们不处理 JSON 有数组的情况。
我在另一个问题中引用的原始函数 DID 处理数组,但它不会处理打包的 JSON。
这是原始函数:
function getPathValue(obj, path) {
return new Function('_', 'return _.' + path)(obj);
}
这是第一个问题的答案:
function getValue(object, path) {
return path
.split('.')
.reduce((o, k) => (typeof o === 'string' ? JSON.parse(o) : o)[k],
object);
}
同样,两者都很好用,但都没有提供完整的服务包。
我需要一个可以同时完成这两个任务的解决方案,并且它必须在 IE11 的 ES5 中运行。
这是一个示例 API 返回 JSON 字符串:
{"id":"0001","type":"donut","name":"Cake","ppu":0.55,"batters":{"batter":[{"id":"1001","type":"Regular"},{"id":"1002","type":"Chocolate"}]},"data":"{\"domain\":\"cooking.com\",\"id\":53819390}"}
我希望能够使用路径字符串查询值,例如:
value = getPathValue(obj, 'batters.batter[2].id');
或
value = getPathValue(obj, 'type');
或
value = getPathValue(obj, 'data.domain');
您可以替换括号并将剩余的值作为键。在减少内部,您可以为未给定的对象使用默认对象。
function getValue(object, path) {
return path
.replace(/\[/g, '.')
.replace(/\]/g, '')
.split('.')
.reduce(function (o, k) {
return (typeof o === 'string' ? JSON.parse(o) : (o || {}))[k];
}, object);
}
var object = {"id":"0001","type":"donut","name":"Cake","ppu":0.55,"batters":{"batter":[{"id":"1001","type":"Regular"},{"id":"1002","type":"Chocolate"}]},"data":"{\"domain\":\"cooking.com\",\"id\":53819390}"},
path = 'batters.batter[1].id';
console.log(getValue(object, path));
以下将对每个值使用正则表达式来完成工作:
const data = {
"id": "0001",
"type": "donut",
"name": "Cake",
"ppu": 0.55,
"batters": {
"batter": [
{
"id": "1001",
"type": "Regular"
},
{
"id": "1002",
"type": "Chocolate"
}
]
},
"data": "{\"domain\":\"cooking.com\",\"id\":53819390}"
}
function getValue(object, path) {
return path
.split('.')
.reduce(function (o, k) {
const indexSearch = (new RegExp(/\[([0-9]*)\]/)).exec(k)
const index = indexSearch ? indexSearch[1] : null
k = k.replace(/\[[0-9]*\]/, '')
const sub = (typeof o === 'string' ? JSON.parse(o) : o)[k]
return index ? sub[index] : sub;
}, object);
}
console.log(getValue(data, 'batters.batter[1]'))
console.log(getValue(data, 'data.domain'))
console.log(getValue(data, 'batters.batter[1].id'))