我从API返回了以下字符串,我想使用javascript将其转换为对象层次结构。
收到的字符串是:
"paymentInfoList.paymentInfo(0).receiver.amount":"12.00"
我想将其转换为javascript对象,如:
{
paymentInfoList: {
PaymentInfo: [{
receiver: {
amount: 12.0
}
}]
}
}
我可以编写自己的解析器,但想知道是否已有一些代码。
更新
根据@JasonCust的答案,这里有一个解析器来解析PayPal自适应付款方式的完整响应: https://github.com/danielflippance/paypal-ap-parser
答案 0 :(得分:2)
我不知道处理该格式的现有解析器。也许在Paypal的开发者网站上有什么东西?如果您自己滚动,可以使用递归函数,如下例所示。我还没有对它进行过彻底的测试,但它是一个很容易做到的POC。
function setObjVal(obj, paths, val) {
var path;
var arrayInfo;
if (paths.length === 0) {
return val;
}
obj = obj || {};
path = paths.shift();
arrayInfo = path.match(arrayRegExp);
if (arrayInfo) {
path = arrayInfo[1];
if (!Array.isArray(obj[path])) {
obj[path] = [];
}
obj[path][arrayInfo[2]] = setObjVal(obj[path][arrayInfo[2]], paths, val);
}
else {
obj[path] = setObjVal(obj[path], paths, val);
}
return obj;
}
var arrayRegExp = /^(\w+)\((\d+)\)$/;
var input = '"paymentInfoList.paymentInfo(0).receiver.amount":"12.00"';
var pair = input.split(':').map(function (str) { return str.replace(/"/g, ''); });
var newObj = setObjVal({}, pair[0].split('.'), pair[1]);
function setObjVal(obj, paths, val) {
var path;
var arrayInfo;
if (paths.length === 0) {
return val;
}
obj = obj || {};
path = paths.shift();
arrayInfo = path.match(arrayRegExp);
if (arrayInfo) {
path = arrayInfo[1];
if (!Array.isArray(obj[path])) {
obj[path] = [];
}
obj[path][arrayInfo[2]] = setObjVal(obj[path][arrayInfo[2]], paths, val);
}
else {
obj[path] = setObjVal(obj[path], paths, val);
}
return obj;
}
document.write('<pre>' + JSON.stringify(newObj, null, 4) + '</pre>');
&#13;
或者如果您想使用lodash,可以使用_.set()
:
var newObj = _.set({}, pair[0].replace(/\(/g, '[').replace(/\)/g, ']'), pair[1]);
var input = '"paymentInfoList.paymentInfo(0).receiver.amount":"12.00"';
var pair = input.split(':').map(function (str) { return str.replace(/"/g, ''); });
var newObj = _.set({}, pair[0].replace(/\(/g, '[').replace(/\)/g, ']'), pair[1]);
document.write('<pre>' + JSON.stringify(newObj, null, 4) + '</pre>');
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.0/lodash.min.js"></script>
&#13;
答案 1 :(得分:2)
由于我无法抗拒一个小谜题,这里有一个干净的递归解决方案,适用于你给出的输入(向下滚动并查看一个小游乐场的片段):
function objectFromExpression(expression, value) {
if (!expression) {
return value;
}
var obj = {};
var matchKeyIdxRest = /^(\w+)(?:\((\d+)\))?(?:\.(.+))?$/;
var matches = expression.match(matchKeyIdxRest);
if (!matches) {
throw new Error('Oops! There\'s a problem with the expression at "' + expression + '"');
}
var key = matches[1];
var idx = matches[2];
var rest = matches[3];
var next = objectFromExpression(rest, value);
if (idx) {
var arr = [];
arr[ parseInt(idx) ] = next;
obj[key] = arr;
} else {
obj[key] = next;
}
return obj;
}
function keyValueExpressionToKeyValue(str) {
var matchKeyVal = /^"([^"]+)":"([^"]+)"$/;
var matches = str.match(matchKeyVal);
if (!matches) {
throw new Error('Oops! Couldn\'t extract key and value from input!');
}
return matches.slice(1);
}
var input = '"paymentInfoList.paymentInfo(0).receiver.amount":"12.00"';
var keyAndValue = keyValueExpressionToKeyValue(input);
var key = keyAndValue[0]; // => paymentInfoList.paymentInfo(0).receiver.amount
var value = keyAndValue[1]; // => 12.00
objectFromExpression(key, value);
// => { paymentInfoList:
// { paymentInfo:
// [ { receiver:
// { amount: "12.00" }
// }
// ]
// }
// }
function objectFromExpression(expression, value) {
if (!expression) {
return value;
}
var obj = {};
var matchKeyIdxRest = /^(\w+)(?:\((\d+)\))?(?:\.(.+))?$/;
var matches = expression.match(matchKeyIdxRest);
if (!matches) {
throw new Error('Oops! There\'s a problem with the expression at "' + expression + '"');
}
var key = matches[1];
var idx = matches[2];
var rest = matches[3];
var next = objectFromExpression(rest, value);
if (idx) {
var arr = [];
arr[ parseInt(idx) ] = next;
obj[key] = arr;
} else {
obj[key] = next;
}
return obj;
}
function keyValueExpressionToKeyValue(str) {
var matchKeyVal = /^"([^"]+)":"([^"]+)"$/;
var matches = str.match(matchKeyVal);
if (!matches) {
throw new Error('Oops! Couldn\'t extract key and value from input!');
}
return matches.slice(1);
}
var inputEl = document.getElementById('input');
function onKeyUp() {
var outputEl = document.getElementById('output');
var input = inputEl.value.trim();
try {
var keyAndValue = keyValueExpressionToKeyValue(input);
var key = keyAndValue[0];
var value = keyAndValue[1];
var output = objectFromExpression(key, value);
outputEl.value = JSON.stringify(output, null, 2);
} catch (ex) {
outputEl.value = ex.toString();
}
}
inputEl.addEventListener('keyup', onKeyUp);
inputEl.dispatchEvent(new Event('keyup'));
label, textarea, input { display: block; }
label { font-family: sans-serif; }
input, textarea { font-family: monospace; width: 100%; margin-bottom: 1em; }
textarea { height: 15em; }
<label for="input">Input (type to see changes)</label>
<input id="input" value='"paymentInfoList.paymentInfo(0).receiver.amount":"12.00"'/>
<label for="output">Output</label>
<textarea id="output">Click the "Parse!" button!</textarea>