问题
I have an object like this,
{
id: '1',
displaName: 'A',
children: [
{
id: '2',
displayName: 'B',
children: [
{
id: '3',
displayName: 'C',
children: [
//More nested array here
]
}
]
}]
}
I just want to change key displayName
with label
so that my object will look like this,
{
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
]
}
]
}]
}
I have tried this but not able to replace key in nested array,
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);
}
Please help me sort out this.
Thanks in advance.
回答1:
You have typo in your code. Some variables are shown as
displaName
instead ofdisplayName
.You need to call a function recursively to work as you intended.
You didn't used
newKeys
variable for renaming. You just have hard-coded it likenewKey = 'label'
. But this issue irrelevant with the problem.
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);
}
回答2:
This is a really generic solution which will traverse through an object and update any object keys that are in the given object literal (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);
回答3:
The existing answers are great, but I can't resist adding a JSON.stringify
version:
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);
Obviously, this won't work if you have a value that looks like a key, so it assumes you have a guarantee of predictable data.
If you have multiple replacements you can use
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);
A more traditional recursive option might be the following (still assumes/hardcodes 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));
Iterative:
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));
来源:https://stackoverflow.com/questions/58533695/how-to-replace-key-in-nested-object