我有一个这样的物体
{
id: '1',
displaName: 'A',
children: [
{
id: '2',
displayName: 'B',
children: [
{
id: '3',
displayName: 'C',
children: [
//More nested array here
]
}
]
}]
}
我只想用displayName
更改键label
,以便我的对象看起来像这样,
{
id: '1',
label: 'A', //change key displayName => label
children: [
{
id: '2',
label: 'B', //change key displayName => label
children: [
{
id: '3',
label: 'C', //change key displayName => label
children: [
//More nested array here
]
}
]
}]
}
我已经尝试过了,但是无法替换嵌套数组中的键,
const newKeys = { displaName: "label"};
const renamedObj = renameKeys(resp.data, newKeys);
console.log(renamedObj);
function renameKeys(obj, newKeys) {
const keyValues = Object.keys(obj).map(key => {
console.log(key);
let newKey = null
if(key === 'displayName'){
newKey = 'label'
}else{
newKey = key
}
console.log(newKey);
return { [newKey]: obj[key] };
});
return Object.assign({}, ...keyValues);
}
请帮助我解决这个问题。
谢谢。
答案 0 :(得分:3)
您的代码中有错字。某些变量显示为const desktopMetricsForm = document.getElementById("desktopMetricsForm");
desktopMetricsForm.addEventListener('submit', function (event) {
const formattedFormData = new FormData(form);
desktopMetricsPostData(formattedFormData);
return false;
})
async function desktopMetricsPostData() {
const response = await fetch('api/get_desktop_metrics.php', {
method: 'GET',
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
body: formattedFormData
});
const data = await response.text();
document.getElementById("desktopMetricsTable").innerHTML = data;
}
而不是displaName
。
您需要递归调用函数才能按预期工作。
您没有使用displayName
变量进行重命名。您只是像newKeys
一样对其进行了硬编码。但是这个问题与问题无关。
newKey = 'label'
答案 1 :(得分:0)
这是一个非常通用的解决方案,它将遍历对象并更新给定对象文字(keysToUpdate
)中的所有对象键。
const orig = {
id: '1',
displayName: 'A',
children: [{
id: '2',
displayName: 'B',
children: [{
id: '3',
displayName: 'C',
children: [
//More nested array here
]
}]
}]
};
const updateDisplayNameToLabel = (val, keysMap) => {
if (val == null) return null;
if (Array.isArray(val)) {
return val.map(item => updateDisplayNameToLabel(item, keysMap));
} else if (typeof val == "object") {
return Object.keys(val).reduce((obj, key) => {
const propKey = updateDisplayNameToLabel(key, keysMap);
const propVal = updateDisplayNameToLabel(val[key], keysMap);
obj[propKey] = propVal;
return obj;
}, {});
} else if (typeof val === "string") {
return keysMap[val] || val;
}
return val;
}
const keysToUpdate = {
displayName: 'label',
children: 'items'
};
const updated = updateDisplayNameToLabel(orig, keysToUpdate);
console.log(updated);
答案 2 :(得分:0)
现有的答案很好,但是我无法抗拒添加JSON.stringify
版本:
const data = { id: '1', displayName: 'A', children: [ { id: '2', displayName: 'B', children: [ { id: '3', displayName: 'C', children: [] }] }] };
const result = JSON.parse(JSON.stringify(data).replace(/"displayName":/g, '"value":'));
console.log(result);
很显然,如果您的值看起来像键,那么这将无法正常工作,因此它假定您可以保证可预测的数据。
如果您有多个替代品,可以使用
const data = { id: '1', displayName: 'A', children: [ { id: '2', displayName: 'B', children: [ { id: '3', displayName: 'C', children: [] }] }] };
const swaps = {displayName: "foo", children: "baz", id: "corge"};
const pattern = new RegExp(
Object.keys(swaps).map(e => `(?:"(${e})":)`).join("|"), "g"
);
const result = JSON.parse(
JSON.stringify(data).replace(pattern, m => `"${swaps[m.slice(1,-2)]}":`)
);
console.log(result);
更传统的递归选项可能是以下内容(仍然假设/硬编码为children
):
const changeKey = (node, keySubs) =>
Object.entries(keySubs).reduce((a, [oldKey, newKey]) => {
a[newKey] = a[oldKey];
delete a[oldKey];
return a;
}, {...node, children: node.children.map(e => changeKey(e, keySubs))})
;
const data = { id: '1', displayName: 'A', children: [ { id: '2', displayName: 'B', children: [ { id: '3', displayName: 'C', children: [] }] }] };
const swaps = {displayName: "label", id: "better id"};
console.log(changeKey(data, swaps));
迭代:
const changeKey = (node, keySubs) => {
const result = {children: []};
const stack = [[node, result]];
while (stack.length) {
const [curr, parent] = stack.pop();
const child = Object.entries(keySubs)
.reduce((a, [oldKey, newKey]) => {
a[newKey] = a[oldKey];
delete a[oldKey];
return a;
}, {...curr, children: []})
;
parent.children.push(child);
stack.push(...curr.children.map(e => [e, child]));
}
return result;
};
const data = { id: '1', displayName: 'A', children: [ { id: '2', displayName: 'B', children: [ { id: '3', displayName: 'C', children: [] }] }] };
const swaps = {displayName: "label", id: "better id"};
console.log(changeKey(data, swaps));