CodeSandbox example https://codesandbox.io/s/throbbing-worker-8s68n?file=/src/index.js
So I have an object and I'm updating the key name by removing the __number, I want to move the the 1st key [ 694 & 695 ] to inside the object as id = 694. I didn't manage to make that happen cause I get a new object for each key value ( see code below ).
var options =
{
"694": {
"title_694": "Tiger",
"category_694": "848",
"description_694": "long description"
},
"695": {
"title_694": "Turtles",
"category_694": "347",
"description_694": "long description"
}
}
and here is my code
Object.keys(options).map( value => (
{
[value] : Object.keys(options[value]).map((keyName) => (
{[keyName.replace(/_*\d /g, '')] : options[value][keyName]}
))
}
)
)
it output as below
[
{
"694": [
{
"title": "Tiger"
},
{
"category": "848"
},
{
"description": "long description"
}
]
},
{
"695": [
{
"title": "Turtles"
},
{
"category": "347"
},
{
"description": "long description"
}
]
}
]
How can make it work to output as below
[
{
"id": 694,
"title": "Tiger",
"category": "848",
"description": "long description"
},
{
"id":695,
"title": "Turtles",
"category": "347",
"description": "long description"
}
]
CodePudding user response:
There is a way to do it without map :
var result = [];
Object.keys(options).forEach((element) => {
result.push({ id: element, ...options[element] });
});
Output:
[
{
"id": "694",
"title_694": "Tiger",
"category_694": "848",
"description_694": "long description"
},
{
"id": "695",
"title_694": "Turtles",
"category_694": "347",
"description_694": "long description"
}
]
Ask me if you have more questions. But you need more code to remove id from new keys object
CodePudding user response:
Using forEach without changing the key names in the original object
var result = [];
Object.keys(options).forEach((element) => {
const item = Object.fromEntries(
Object.entries(options[element]).map(([k, v]) => {
k = k.replace(/_*\d /g, "");
return [k, v]
})
)
result = [...result,{ id: element, ...item }]
});
document.getElementById("app").innerHTML = `<pre>${JSON.stringify(
result,
null,
4
)}</pre>`;
console.log(result);
The output
[
{
"id": "694",
"title": "Tiger",
"category": "848",
"description": "long description"
},
{
"id": "695",
"title": "Turtles",
"category": "347",
"description": "long description"
}
]
CodePudding user response:
Personally like you, I prefer not to manually build a whole new array.
var options = {
"694": {
"title_694": "Tiger",
"category_694": "848",
"description_694": "long description"
},
"695": {
"title_694": "Turtles",
"category_694": "347",
"description_694": "long description"
}
}
let mutated = Object.values(Object.entries(options).map(([id, option]) => {
return Object.assign({
id: id,
}, Object.fromEntries(Object.entries(option).map(([key, value]) => {
return [key.replace(/_*\d $/g, ''), value];
})));
}));
This lets the first map
function create a new array accordingly, Object.assign
ensures you have a single object from each, and the Object.entries
and Object.fromEntries
to convert to an array of pairs to then convert the keys, and then back from the array of pairs.
Have a read of the MDN documentation relating to Object.entries
: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries
That links to the Object.fromEntries
documentation, too.
As a side note, I've modified your regular expression to include the end-of-line match so it will modify something like w3tag_694
in the expected way. I would also suggest looking at changing the *
in the regex to a
to be a little stricter.
There is a caveat: fromEntries
is a relatively new feature, but is supported by all major browsers still supported by their makers. Check the support: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/fromEntries#browser_compatibility