Reputation: 2126
I have an object like this:
const player = {
id: 123,
country: 'GB',
names: {
key1: 'John Paul',
key2: 'Johny Paul',
key3: 'Johny-paul'
}
}
Then I want to apply a function to all names
values:
const normalizeString = el => el.normalize('NFD').replace(/[\u0300-\u036f]/g, "");
const normalizedPlayer = {
...player,
namesNormalized: Object.keys(player.names).map(k => ({[k]: normalizeString(player.names[k])}))
}
But I get an array of objects instead of object:
{
id: 123,
country: 'GB',
names: { key1: 'Jóhn Paul', key2: 'Johny Päul', key3: 'Johny-paul' },
namesNormalized: [
{ key1: 'John Paul' },
{ key2: 'Johny Paul' },
{ key3: 'Johny paul' }
]
}
I want namesNormalized
like this:
{
id: 123,
country: 'GB',
names: { key1: 'Jóhn Paul', key2: 'Johny Päul', key3: 'Johny-paul' },
namesNormalized: {
key1: 'John Paul',
key2: 'Johny Paul',
key3: 'Johny paul'
}
}
Upvotes: 1
Views: 1421
Reputation: 245
You could loop through each key of the object and then assign that key to the normalized version, like this:
const generateNormalizedObj = (obj) => {
const normalizedObj = {};
Object.keys(obj).forEach(key => {
normalizedObj[key] = obj[key];
})
return normalizedObj;
}
Then you could simply set the namesNormalized
property in the last variable to be output of that function.
Here's the final code:
const player = {
id: 123,
country: 'GB',
names: {
key1: 'John Paul',
key2: 'Johny Paul',
key3: 'Johny-paul'
}
}
const normalizeString = el => el.normalize('NFD').replace(/[\u0300-\u036f]/g, "");
const normalizedPlayer = {
...player,
namesNormalized: Object.keys(player.names).map(k => ({[k]: normalizeString(player.names[k])}))
}
const generateNormalizedObj = (obj) => {
const normalizedObj = {};
Object.keys(obj).forEach(key => {
normalizedObj[key] = obj[key];
})
return normalizedObj;
}
const normalizedPlayer = {
...player,
namesNormalized: generateNormalizedObj(player.names)
}
Upvotes: 0
Reputation: 11047
Another possibility is using Object.entries
combined with Object.fromEntries
.
This lets you avoid having to deal with reducing the properties as fromEntries
turns the entries format back to an object.
From Entries works on pretty much all modern major browsers (Can I Use), but there is a shim for it if needed on older browsers.
const player = {
id: 123,
country: 'GB',
names: {
key1: 'Jóhn Paul',
key2: 'Johny Päul',
key3: 'Johny-paul'
},
}
const normalizeString = el => el.normalize('NFD').replace(/[\u0300-\u036f]/g, "");
const normalizeObject = (obj) => Object.fromEntries(Object.entries(obj).map(([k, v]) => [k, normalizeString(v)]))
const normalizedPlayer = {
...player,
namesNormalized: normalizeObject(player.names)
}
console.log(normalizedPlayer)
Upvotes: 3
Reputation: 2126
Thanks to @Heretic Monkey to use reduce:
const player = {
id: 123,
country: 'GB',
names: {
key1: 'John Paul',
key2: 'Johny Paul',
key3: 'Johny-paul'
}
}
const normalizeString = el => el.normalize('NFD').replace(/[\u0300-\u036f]/g, "");
const normalizedPlayer = {
...player,
namesNormalized: Object.keys(player.names).reduce( (a, k) => ({...a, [k]: normalizeString(player.names[k])}) , {})
}
Upvotes: 1
Reputation: 1156
const player = {
id: 123,
country: 'GB',
names: {
key1: 'John Paul',
key2: 'Johny Paul',
key3: 'Johny-paul'
}
}
const normalizeString = el => el.normalize('NFD').replace(/[\u0300-\u036f]/g, "");
const normalizedPlayer = {
...player,
namesNormalized: Object.keys(player.names).reduce((namesNormalized, k) => {
return {
...namesNormalized, // spread over previous key/value pairs
[k]: normalizeString(player.names[k]) // store current key/value pair
}
}, {}) // initial value for reducer is an empty object
}
Upvotes: 0
Reputation: 122155
You can use reduce
method on Object.entries
to return an object and assign it to namesNormalized
property.
const player = {
id: 123,
country: 'GB',
names: {
key1: 'John Paul',
key2: 'Johny Paul',
key3: 'Johny-paul'
}
}
const normalizeString = el => el.normalize('NFD').replace(/[\u0300-\u036f]/g, "");
const normalizedPlayer = { ...player }
normalizedPlayer.namesNormalized = Object.entries(player.names)
.reduce((r, [k, v]) => Object.assign(r, {
[k]: normalizeString(v)
}), {})
console.log(normalizedPlayer)
Upvotes: 1