3 回答
TA贡献1828条经验 获得超4个赞
你的代码有错别字。某些变量显示为
displaName
而不是displayName
。您需要递归调用函数才能按预期工作。
您没有使用
newKeys
变量进行重命名。你只是硬编码它像newKey = 'label'
. 但是这个问题与问题无关。
const resp = {
data: {
id: '1',
displayName: 'A',
children: [{
id: '2',
displayName: 'B',
children: [{
id: '3',
displayName: 'C',
children: [
//More nested array here
]
}]
}]
}
}
const newKeys = {
displayName: "label"
};
const renamedObj = this.renameKeys(resp.data, newKeys);
console.log(renamedObj);
function renameKeys(obj, newKeys) {
const keyValues = Object.keys(obj).map(key => {
let newKey = null
if (key === 'displayName') {
newKey = newKeys.displayName
} else {
newKey = key
}
if (key === 'children') {
obj[key] = obj[key].map(obj => renameKeys(obj, newKeys));
}
return {
[newKey]: obj[key]
};
});
return Object.assign({}, ...keyValues);
}
TA贡献1842条经验 获得超12个赞
这是一个非常通用的解决方案,它将遍历一个对象并更新给定对象字面量 ( 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);
TA贡献1876条经验 获得超7个赞
现有的答案很好,但我无法抗拒添加一个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));
添加回答
举报