0

I have an object with concrete structure. I want to create another one, with other structure...Something like .map()

const Object: Icon = {
  Laughing: {
    iconClass: 'emoticon-3',
    name: 'Laughing :D',
    dataText: ':D',
  },
  Surprise: {
    iconClass: 'emoticon-4',
    name: "Surprise, No you di'int' :O",
    dataText: ':O',
  }
  .......
}

and I want to map it to other object structure:

const Object2: Type2 = {
  :D: {
    iconClass: 'emoticon-3',
    name: 'Laughing :D',
  },
  :O: {
    iconClass: 'emoticon-4',
    name: "Surprise, No you di'int' :O",
  }
  .......
}
1
  • 1
    You are stating a requirement. Please also try to add what you tried and on what front you are facing the issue with the data transformation. Commented Mar 13, 2019 at 9:32

3 Answers 3

2

You can use Object.values() and reduce. Use destructuring to get dataText as a separate variable and the remaining properties to a rest variable like this: { dataText, ...rest }

const obj = {
  Laughing: {
    iconClass: 'emoticon-3',
    name: 'Laughing :D',
    dataText: ':D',
  },
  Surprise: {
    iconClass: 'emoticon-4',
    name: "Surprise, No you di'int' :O",
    dataText: ':O',
  }
}

const newObj = Object.values(obj).reduce((acc, { dataText, ...rest }) => {
  acc[dataText] = rest;
  return acc
}, {})

console.log(newObj)

As @jo_va suggested, you could also implicitly return from the reduce:

Object.values(obj).reduce((acc, { dataText, ...rest }) => ({ ...acc, [dataText]: rest }), {})
Sign up to request clarification or add additional context in comments.

2 Comments

You can shorten the body with an implicit return ({ ...acc, [dataText]: rest })
@jo_va you're right. I've added that to the answer.
1

You can use array#map to create array of object and then using Object.assign() create a single object.

const obj = { Laughing: { iconClass: 'emoticon-3', name: 'Laughing :D', dataText: ':D', }, Surprise: { iconClass: 'emoticon-4', name: "Surprise, No you di'int' :O", dataText: ':O', } },
    result = Object.assign(...Object.values(obj).map(({dataText, ...o}) => ({[dataText] : o})));
console.log(result);

Comments

0

Old school solution - just iterate over original object's fields and gradually create the new object.

const dstObject = {};
for (const fieldName in srcObject) {
  if (Object.hasOwn(srcObject, fieldName)) {
    const oldFieldValue = srcObject[fieldName];
    const newFieldName = ... // create new field name
    const newFieldValue = ... // create new fieldValue
    dstObject[newFieldName] = newFieldValue;
  }
}

More array.map-like solution.

  • Decompose original object to an array of entries using Object.entries.
  • .map over that array to create new entries.
  • Create new object from the new entries using Object.fromEntries.
const srcEntries = Object.entries(srcObject);
const dstEntries = srcEntries.map(([fieldName, fieldValue]) => {
  const newFieldName = ... // create new field name
  const newFieldValue = ... // create new fieldValue
  return [newFieldName, newFieldValue];
});
const dstObject = Object.fromEntries(dstEntries);

The first solution doesn't create additional garbage for GC to collect, but the second might be easier to understand.

And both versions will probably make typescript unhappy, so you will probably have to do some additional type assertions.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.