2 回答
TA贡献1798条经验 获得超7个赞
这是规范化对象的 es5 方法
function normalisedObject(object) {
var normalised = {};
for (var key in object) {
//regex to capture all [.*] groups
var matches = key.match(/\[(.*?)\]/g);
if (matches) {
var temp = normalised;
while (matches.length > 0) {
//get first key and replace []
var newKey = matches[0].replace(/\[|\]/g, "");
if (matches.length !== 1) {
//keep traverse if the left over keys are greater than 1
temp = temp[newKey] || (temp[newKey] = {}); //assign empty object
} else {
temp[newKey] = object[key];
}
//poll
matches.shift();
}
}
}
return normalised;
}
//example
const t1 = performance.now();
var object = {
"userChoice[language]": "en",
"userChoice[responses][favColor]": "black",
"userChoice[responses][favCity]": "new york"
};
var normalised = normalisedObject(object);
const t2 = performance.now();
console.log(`Operation took ${t2 - t1}ms`);
console.log(normalised);
TA贡献1811条经验 获得超5个赞
当对象的键不允许您使用简单的点表示法时,即obj.property,您可以使用方括号表示法,例如
const lang = obj["userChoice[language]"]
但我有一种感觉,你真的想把那个物体变成类似这个的东西
{
userChoice: {
language: "en",
responses: {
favColor: "black",
favCity: "new york"
}
}
}
如果是这种情况,您需要将对象条目(键/值对)减少到一个新对象,解析出关键路径并构建新的内部对象
const obj = {
"userChoice[language]": "en",
"userChoice[responses][favColor]": "black",
"userChoice[responses][favCity]": "new york",
}
const t1 = performance.now()
const normalised = Object.entries(obj).reduce((c, [ key, val ]) => {
// get the key parts as a path array
const path = key.replace(/]/g, "").split(/\[/)
// pop the last property for assigning the value later
const prop = path.pop()
// determine the inner-most object by path
const inner = path.reduce((o, k) => {
// create a new object if it doesn't exist
return o[k] ?? (o[k] = {})
}, c)
// assign the value
inner[prop] = val
return c
}, {})
const t2 = performance.now()
console.info(normalised)
console.log(`Operation took ${t2 - t1}ms`)
.as-console-wrapper { max-height: 100% !important; }
请注意,如果您开始将任何数组属性放入 eg 中userChoice[foo][0]
,这将不起作用。
添加回答
举报