0

I'm struggling with the following task.

On the one hand I have the following object:

[
  {
    name: "VALUE1",
    type: "select",
    label: "Label"
  },
  {
    name: "VALUE2",
    type: "select",
    label: "Label"
  },
  {
    name: "VALUE3",
    type: "select",
    label: "Label"
  },
];

On the other hand I have some content for the object above, with I want to merge in a new object.
Here's the content:

[
  {
    VALUE1: "CONTENT",
    VALUE2: "CONTENT",
    VALUE3: "CONTENT",
    VALUE4: "CONTENT",
    VALUE5: "CONTENT",
  },
  {
    VALUE1: "CONTENT",
    VALUE2: "CONTENT",
    VALUE3: "CONTENT",
    VALUE4: "CONTENT",
    VALUE5: "CONTENT",
  },
  {
    VALUE1: "CONTENT",
    VALUE2: "CONTENT",
    VALUE3: "CONTENT",
    VALUE4: "CONTENT",
    VALUE5: "CONTENT",
  }
]

Please notice that the key from the second object matches with the value from the first
At the end I need a object which should have the following structure:

[
  {
    name: 'VALUE1'
    id: 'CONTENT 1 ',
    label: 'LABEL 1',
    type: 'select'
    selectMenuOptions: {
      VALUE1: "CONTENT",
      VALUE1: "CONTENT",
      VALUE1: "CONTENT",
      VALUE1: "CONTENT",
      VALUE1: "CONTENT",
    }
  },
  {
    name: 'VALUE2'
    id: 'CONTENT 2 ',
    label: 'LABEL 2',
    type: 'select'
    selectMenuOptions: {
      VALUE2: "CONTENT",
      VALUE2: "CONTENT",
      VALUE2: "CONTENT",
      VALUE2: "CONTENT",
      VALUE2: "CONTENT",
    }
  },
  {
    name: 'VALUE3'
    id: 'CONTENT 3 ',
    label: 'LABEL 3',
    type: 'select'
    selectMenuOptions: {
      VALUE3: "CONTENT",
      VALUE3: "CONTENT",
      VALUE3: "CONTENT",
      VALUE3: "CONTENT",
      VALUE3: "CONTENT",
    }
  },
]

Some background information if it helps:

  • Angular 14
  • The object I try to form is for dynamic forms
Heretic Monkey
  • 11,687
  • 7
  • 53
  • 122
kayza
  • 75
  • 1
  • 10
  • 4
    Instead of writing full sentences in your example result, please show the *actual* result you are expecting. It seems like your second array is missing some properties as well. You can include comments for clarity if needed. – Chris Hamilton Aug 23 '22 at 16:15
  • @ChrisHamilton thx a lot, I make a big mistake on my question. I edited now – kayza Aug 23 '22 at 16:57
  • You say you've been struggling, but provide no code showing your struggles. It could be you're 90% of the way there and just need to know a simple trick to get you where you need to be. It would be better if you would provide your attempts so that answerers didn't have to start from scratch and do all your work for you. – Heretic Monkey Aug 23 '22 at 17:07
  • @kayza how should the id be generated? Is it based on index in the array, or are you parsing the number from one of the strings? – Chris Hamilton Aug 23 '22 at 17:19
  • @kayza do you actually want the label to change, or is that just a typo? – Chris Hamilton Aug 23 '22 at 17:21
  • 1
    @kayza the result you gave is also impossible since you have duplicate keys – Chris Hamilton Aug 23 '22 at 17:36
  • @ChrisHamilton the id get I from the the content in the second object. – kayza Aug 24 '22 at 10:20
  • @ChrisHamilton the relationship is built using the keys of the second object and the values of the first object – kayza Aug 24 '22 at 10:29
  • @ChrisHamilton this is the answer for: the result you gave is also impossible since you have duplicate keys oh, that's right, that's a logical error i have to clarify. thanks for pointing that out – kayza Aug 24 '22 at 10:33

2 Answers2

1

it is not very clear what data structure you wish to have. I will put you a simple example of a "merge" of this data, inspired by this you should be able to get to your goal.

const a = [
  {
    name: "VALUE1",
    type: "select",
    label: "LABEL 1"
  },
  {
    name: "VALUE2",
    type: "select",
    label: "LABEL 2"
  },
  {
    name: "VALUE3",
    type: "select",
    label: "LABEL 3"
  },
]
const b = [
  {
    VALUE1: "CONTENT 1",
    VALUE2: "CONTENT 2",
    VALUE3: "CONTENT 3",
    VALUE4: "CONTENT 4",
    VALUE5: "CONTENT 5",
  },
  {
    VALUE1: "CONTENT 1",
    VALUE2: "CONTENT 2",
    VALUE3: "CONTENT 3",
    VALUE4: "CONTENT 4",
    VALUE5: "CONTENT 5",
  },
  {
    VALUE1: "CONTENT 1",
    VALUE2: "CONTENT 2",
    VALUE3: "CONTENT 3",
    VALUE4: "CONTENT 4",
    VALUE5: "CONTENT 5",
  }
]

const merged = a.map(element => {
  element.selectMenuOptions = b.map(be => ({ [element.name]: be[element.name] }))
  return element
});
Jacopo Bonomi
  • 448
  • 3
  • 10
  • 1
    thx, for your answer. But i make a mistake on my question and edited now. I hope now it's clearer to understand my struggle. – kayza Aug 23 '22 at 17:01
  • Ok i edit my answer, i think now it's ok for your goal. – Jacopo Bonomi Aug 23 '22 at 17:08
  • 1
    thank you a lot, this helps me for now. in this case I have the problem, that I have all the `element.name` in a single object. this should be fixed. but the bigger problem is, that all the keys are the same, but this is was my mess, not yours. A logical problem, that I didn't see. thank you again – kayza Aug 24 '22 at 10:56
1

Given these arrays:

const arr1 = [
  {
    name: "VALUE1",
    type: "select",
    label: "LABEL1"
  },
  {
    name: "VALUE2",
    type: "select",
    label: "LABEL2"
  },
  {
    name: "VALUE3",
    type: "select",
    label: "LABEL3"
  },
];
const arr2 = [
  {
    VALUE1: "CONTENT01",
    VALUE2: "CONTENT02",
    VALUE3: "CONTENT03",
    VALUE4: "CONTENT04",
    VALUE5: "CONTENT05",
  },
  {
    VALUE1: "CONTENT11",
    VALUE2: "CONTENT12",
    VALUE3: "CONTENT13",
    VALUE4: "CONTENT14",
    VALUE5: "CONTENT15",
  },
  {
    VALUE1: "CONTENT21",
    VALUE2: "CONTENT22",
    VALUE3: "CONTENT23",
    VALUE4: "CONTENT24",
    VALUE5: "CONTENT25",
  }
]

You can merge them like so:

function merge() {
  const map = new Map<string, string[]>();
  for (const obj of arr2) {
    for (const key of Object.keys(obj)) {
      if (!map.get(key)) map.set(key, []);
      map.get(key).push(obj[key]);
    }
  }
  for (const obj of arr1) {
    obj['selectMenuOptions'] = map.get(obj.name) || [];
  }
}

Which causes arr1 to look like this:

[
  {
    name: 'VALUE1',
    type: 'select',
    label: 'LABEL1',
    selectMenuOptions: ['CONTENT01', 'CONTENT11', 'CONTENT21'],
  },
  {
    name: 'VALUE2',
    type: 'select',
    label: 'LABEL2',
    selectMenuOptions: ['CONTENT02', 'CONTENT12', 'CONTENT22'],
  },
  {
    name: 'VALUE3',
    type: 'select',
    label: 'LABEL3',
    selectMenuOptions: ['CONTENT03', 'CONTENT13', 'CONTENT23'],
  },
]

I've excluded id since you haven't provided any information on how to generate the id, and presumably name is unique, so it should function as an id.

Also, you can't have an object like:

const obj = {
  VALUE1: 'CONTENT1',
  VALUE1: 'CONTENT2',
  VALUE1: 'CONTENT3',
}

What would obj.VALUE1 return in this case?

So I made selectMenuOptions an array instead.


Stackblitz: https://stackblitz.com/edit/typescript-txtmnf?file=index.ts

Chris Hamilton
  • 9,252
  • 1
  • 9
  • 26