Home > Software design >  Javascript merge some properties of 2 arrays
Javascript merge some properties of 2 arrays

Time:06-30

I have 2 arrays with objects inside them:

names = [
    {
        "name": "B"
    },
    {
        "name": "C"
    },
    {
        "name": "D"
    },
    {
        "name": "B"
    },
    {
        "name": "A"
    }
]


 sections = [
    {
        "id": 3638,
        "name": "B",
        "type": "PANEL",
        "parentSectionId": 3635,
        "order": 1,
        "page": "595"
    },
    {
        "id": 3658,
        "name": "C",
        "type": "PANEL",
        "parentSectionId": 3635,
        "order": 2,
        "page": "595"
    },
    {
        "id": 3659,
        "name": "D",
        "type": "PANEL",
        "parentSectionId": 3635,
        "order": 3,
        "page": "595"
    },
    {
        "id": 3636,
        "name": "A",
        "type": "PANEL",
        "parentSectionId": 3635,
        "order": 4,
        "page": "595"
    },
    {
        "id": 3661,
        "name": "B",
        "type": "PANEL",
        "parentSectionId": 3635,
        "order": 5,
        "page": "595"
    }
]

I need to merge some propoerties of sections array inside names array. The properties to be merged are: id and order.

The problem is with id. Because there is one duplicate name: 'B' the id is being duplicated.

I tried many things, but they fail because puts same ID 3638 on both duplicate names: 'B'.

Here is the final output:

section {id: 3638, name: 'B', order: 1, size: undefined}
section {id: 3658, name: 'C', order: 2, size: undefined}
section {id: 3659, name: 'D', order: 3, size: undefined}
section {id: 3638, name: 'B', order: 4, size: undefined}
section {id: 3636, name: 'A', order: 5, size: undefined}

And here my last code attempt:

 const childrens = names.map((c, i) => ({
        ...c,
        id: this.sections.find((s) => s.name === c.name).id,
        order: i   1,
      }));

CodePudding user response:

As far as I understood, this code will preserve the order for duplicate names (it's a raw version for a proof of concept)

 merged = []
 visited = []
  
  for (let i=0; i<names.length; i  ) {
    for (let j=0; j<sections.length; j  ) {
      if ((names[i].name === sections[j].name) && !visited.find(e => e === sections[j].id) ) {
        const obj = {...names[i]}
        obj['order'] = sections[j].order
        obj['id'] = sections[j].id
        merged.push(obj)
        visited.push(sections[j].id)
        continue
      }
    }
  }

console.log(merged)

output:

[
  { name: 'B', order: 1, id: 3638 },
  { name: 'B', order: 5, id: 3661 },
  { name: 'C', order: 2, id: 3658 },
  { name: 'D', order: 3, id: 3659 },
  { name: 'A', order: 4, id: 3636 }
]

CodePudding user response:

I think you were going in the right direction

For full merge, use :

let children = names.map((name, index) => { 
  return({
    order: index  1,
    name: name.name,
    ...sections[index]
  })
})

For partial merge :

let children = names.map((name, index) => { 
  return({
    name: name.name,
    order: index 1,
    id: sections[index].id
  })
})

I think you don't need the .find() and only use indexes

  • Related