最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Transform an object with objects in it - Stack Overflow

programmeradmin1浏览0评论

I have the following key/value object

form: {
  id: {value: this.item.id, hidden: true},
  title: {value: this.item.title},
  translations: {
    en: {
      locale: {value: 'en', hidden: true},
      name: {value: 'Hello World'}
    },
    nl: {
      locale: {value: 'nl', hidden: true},
      name: {value: 'Hallo Wereld'}
    }
  }
}

So each key has an object with a value and a hidden attribute, I'm stuck on how to achieve the following. Transform the nested object so each key just has it's value. Not the object with value and hidden. The big issue it seems for me is that it's nested.. So it has to work recursive.

This is the desired end result

form: {
  id: this.item.id,
  title: this.item.title,
  translations: {
    en: {
      locale: 'en',
      name: 'Hello World'
    },
    nl: {
      locale: 'nl',
      name: 'Hallo Wereld'
    }
  }
}

I've tried

Using a bination of Object.keys(form).map(...), which gives me the key of each item, but that's not going to work recursive I'm afraid.

I have the following key/value object

form: {
  id: {value: this.item.id, hidden: true},
  title: {value: this.item.title},
  translations: {
    en: {
      locale: {value: 'en', hidden: true},
      name: {value: 'Hello World'}
    },
    nl: {
      locale: {value: 'nl', hidden: true},
      name: {value: 'Hallo Wereld'}
    }
  }
}

So each key has an object with a value and a hidden attribute, I'm stuck on how to achieve the following. Transform the nested object so each key just has it's value. Not the object with value and hidden. The big issue it seems for me is that it's nested.. So it has to work recursive.

This is the desired end result

form: {
  id: this.item.id,
  title: this.item.title,
  translations: {
    en: {
      locale: 'en',
      name: 'Hello World'
    },
    nl: {
      locale: 'nl',
      name: 'Hallo Wereld'
    }
  }
}

I've tried

Using a bination of Object.keys(form).map(...), which gives me the key of each item, but that's not going to work recursive I'm afraid.

Share Improve this question edited Mar 12, 2019 at 13:01 Miguel Stevens asked Mar 12, 2019 at 12:58 Miguel StevensMiguel Stevens 9,25019 gold badges75 silver badges136 bronze badges 5
  • Thanks for spotting the typo, Mamun, it's fixed now. – Miguel Stevens Commented Mar 12, 2019 at 13:01
  • Obtaining the value from keys and checking for typeOf and if that results to object, then get the keys for that object perhaps? – Krishna Prashatt Commented Mar 12, 2019 at 13:04
  • All values are objects, as you can see in my first code block. – Miguel Stevens Commented Mar 12, 2019 at 13:06
  • Make a recursive function that takes an object as a parameter. Loop over keys and check if it is an object then call the function with the new object as parameter – DTul Commented Mar 12, 2019 at 13:06
  • I may be wrong but I dont think lines like this.item.id & this.item.title & so on will actually work. Self referencing during object initializing seems dont work – brk Commented Mar 12, 2019 at 13:37
Add a ment  | 

2 Answers 2

Reset to default 17

function transform(obj) {
  return Object.entries(obj).reduce((newObj, [name, value]) => ({ ...newObj, [name]: value.value === undefined ? transform(value) : value.value  }), {})
}

const form = {
  id: {value: '77777', hidden: true},
  title: {value: '11111'},
  translations: {
    en: {
      locale: {value: 'en', hidden: true},
      name: {value: 'Hello World'}
    },
    nl: {
      locale: {value: 'nl', hidden: true},
      name: {value: 'Hallo Wereld'}
    }
  }
}

console.log(transform(form))

Explanation:

function transform(obj) {
  const entries = Object.entries(obj) // transform object to Array<[propertyName, propertyValue]>

  const tranformedObject = entries.reduce(reducer, {}) // inital value for the first arg of reducer is {}

  return tranformedObject
}

function reducer(newObj, [propertyName, propertyValue]) { // name 
  return {
    ...newObj, // get all properties (that we already set) from prev newObj
    [propertyName]: propertyValue.value === undefined ? transform(propertyValue) : propertyValue.value // if property has .value use it or use recursively tranformed object
  }  // returned value will be set to newObj, and than returned to tranformedObject
}

{ ...prop, [name]: vaue } - it's ES6 syntax

I don't know about performance of this solution, but it's really small

function transform(obj) {
  return JSON.parse(JSON.stringify(obj, (key, value) => "value" in value ? value.value : value))
}

const form = {
  id: {value: '77777', hidden: true},
  title: {value: '11111'},
  translations: {
    en: {
      locale: {value: 'en', hidden: true},
      name: {value: 'Hello World'}
    },
    nl: {
      locale: {value: 'nl', hidden: true},
      name: {value: 'Hallo Wereld'}
    }
  }
}

console.log(transform(form))

Explanation: JSON.stringify accepts replacer parameter which can be used to transform any value as you want

// My mind was blown when i figured this solution

发布评论

评论列表(0)

  1. 暂无评论