James Bertaha
James Bertaha

Reputation: 55

Javascript - transform an object of array list to another format?

So I've been stumped on this for hours and I can't really figure out an elegant solution to solve this problem. Let's say I have this:

let Fields = {
  GAME: [
    { code: '{{GTAV}}', title: { en: "grnti"} },
    { code: '{{GTA5}}', title: { en: "Grand theph " } },
  ]
};

How can I turn this into a new format that looks like this ?

let Fields = {
  tags: [
    { name: 'GAME', tags:[
            { name: 'grnti', value: "{{GTAV}}" },
            { name: 'Grand theph', value: "{{GTA5N}}" }
          ]},
  ]};

I tried to create a function to do the job , but for some reason my brain cannot seem to grasp the solution. Any help please !

Upvotes: 0

Views: 74

Answers (4)

richytong
richytong

Reputation: 2452

Here's a clean way that may seem a bit like magic, but I'll walk you through what's going on.

let Fields = {
  RECIPIENT: [
    { code: '{{RECIPIENT.LN}}', title: { en: "name"} },
    { code: '{{RECIPIENT.FN}}', title: { en: "first name" } },
  ]
};

const { pipe, fork, map, get } = rubico

const Transformed = pipe([
  Object.entries, // { RECIPIENT: [...] } => [['RECIPIENT', [...]]
  fork({
    mergeTags: map(fork({ // iterate through each entry ['RECIPIENT', [...]]
      name: get(0), // name is the item at index 0 of each entry
      mergeTags: pipe([
        get(1), // mergeTags starts with index 1 of each entry, the array of code+title objects
        map(fork({ // iterate through the array of code + title objects and create new objects
          name: get('title.en'), // name is title.en of each object
          value: get('code'), // value is title.code of each object
        })),
      ]),
    })),
  }),
])(Fields)

console.log(JSON.stringify(Transformed, null, 2))
<script src="https://unpkg.com/rubico"></script>

Disclaimer: I am the author of rubico

You can examine these methods in depth at the documentation

Upvotes: 0

Scott Sauyet
Scott Sauyet

Reputation: 50797

A simple version of this might look like the following:

const transform = (fields) => ({
  mergeTags: Object .entries (fields) .map (([name, innerFields]) => ({
    name, 
    mergeTags: innerFields .map (({code, title: {en}}) => ({name: en, value: code}))
  }))
})

const fields = {RECIPIENT: [{code: '{{RECIPIENT.LN}}', title: {en: "name"}}, {code: '{{RECIPIENT.FN}}', title: {en: "first name" }}]}

console .log (transform (fields))

But from your nested mergeTags properties, I'm guessing that there is something recursive going on. If so, we need more information about the input and output structures.

Upvotes: 1

peinearydevelopment
peinearydevelopment

Reputation: 11474

It is hard to tell exactly from your question what you are hoping to accomplish as well as the shape of your data. Based on your question though, you would probably want to use the Object.keys and map functions

let Fields = {
  RECIPIENT: [
    { code: '{{RECIPIENT.LN}}', title: { en: "name" } },
    { code: '{{RECIPIENT.FN}}', title: { en: "first name" } },
  ]
};

// gets the keys of the 'Fields' object(in this case only 'RECIPIENT'
let newFields = Object.keys(Fields)
                      // each key should create a new object with the 'key' from the original object as the 'name' of the new object
                      .map(key => ({
                        name: key,
                        // 'Fields[key]' gets the array from the 'RECIPIENT' property and then creates a new object from each object in the original array, mapping the 'title.en' property in the original object to 'name' in the new object and 'code' in the original object to 'value' in the new object
                        mergeTags: Fields[key].map(property => ({
                          name: property.title.en,
                          value: property.code
                        }))
                      }));

console.log(newFields);

Upvotes: 0

Domino987
Domino987

Reputation: 8774

i just threw a nested reduce function together.

const transformed = Object.entries(Fields).reduce((tags, [key, value]) => {
    const mergedTags = value.reduce((codes, code) => {
        codes.mergeTags.push({name: code.title.en, value: code.code});
        return codes;
    }, {name: key, mergeTags: []})
    tags.mergeTags.push(mergedTags)
        return tags;
}, {mergeTags: []})

Does that work for you?

Upvotes: 0

Related Questions