简体   繁体   中英

JS apply function to all values of object

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' 
   }
 } 

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(/[\̀-\ͯ]/g, ""); const normalizedPlayer = { ...player } normalizedPlayer.namesNormalized = Object.entries(player.names) .reduce((r, [k, v]) => Object.assign(r, { [k]: normalizeString(v) }), {}) console.log(normalizedPlayer)

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)
}

I hope this helps!

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
}

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])}) , {})
}

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(/[\̀-\ͯ]/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)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM