0

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 !

1
  • 4
    Welcome to Stack Overflow! Please take the tour (you get a badge!) and read through the help center, in particular How do I ask a good question? Your best bet here is to do your research, search for related topics on SO, and give it a go. (It sounds like you may have already done that!) If you get stuck and can't get unstuck after doing more research and searching, post a minimal reproducible example of your attempt and say specifically where you're stuck. People will be glad to help. Commented Jun 25, 2020 at 16:01

4 Answers 4

1

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.

Sign up to request clarification or add additional context in comments.

2 Comments

Thank youu that's verry useful , what if i have in title: { fr: "nom", nl: "nume", en: "name" } , how can i call a parmeter in the method ======> const transform = (fields,lng)
I'd suggest you either update this question with the additional requirement, or, probably better, open a new question. Try to give more detail than you do in this question about the kinds of structures you support. That said, if I understand correctly, this might work: ...innerFields .map (({code, title: {[lng]: ln}}) => ({name: ln, value: code})) ...
0

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?

Comments

0

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

Comments

0

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

1 Comment

rubico looks very interesting! Note, though that neither this version or my Ramda version seem to have much of an advantage over my simple ES6 answer.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.