Merging multiple arrays in javascript?

I have this code that supposed to merge 3 arrays based on a matching siteid.

This works to an extend. Basically, it only finds 1 siteid and ignores the Same siteides!

This is the code:

if you run the code below, you see that it only adds one of the forms with siteid of 77 to the merged Array! but it should add all the forms with the same siteid (77 in this example) to the merged array.

var siteS1 = [{
    Date: '2021-02-02 11:19',
    siteid: 77,
  },
  {
    Date: '2021-02-02 11:19',
    siteid: 76,
  },
  {
    Date: '2021-02-02 11:19',
    siteid: 66,
  },
  {
    Date: '2021-02-02 11:19',
    siteid: 96,
  }
];


var siteS2 = [{
    Date: '2021-02-02 11:19',
    siteid: 77,
  },
  {
    Date: '2021-02-02 11:19',
    siteid: 76,
  },
  {
    Date: '2021-02-02 11:19',
    siteid: 66,
  },
  {
    Date: '2021-02-02 11:19',
    siteid: 96,
  }
];

var form = [{
    data: {},
    siteid: 77,
  },
  {
    data: {},
    siteid: 77,
  },
  {
    data: {},
    siteid: 77,
  },
  {
    data: {},
    siteid: 96,
  }
];

const merge = (...arrayList) => {
  const siteids = arrayList
    .map(array => array.map(item => item.siteid))
    .flat()
  return Array.from(new Set(siteids))
}

const find = (siteid, array) => {
  const found = array.find(item => item.siteid === siteid)
  if (!found) return undefined // returns undefined if item was not found
  const {
    siteid: _,
    ...restFoundData
  } = found // omit `siteid` from found item
  return restFoundData
}

const populate = (siteids) => siteids.map(siteid => {
  const foundSiteS1 = find(siteid, siteS1)
  const foundSiteS2 = find(siteid, siteS2)
  const foundForm = find(siteid, form)
  return {
    siteS1: foundSiteS1,
    siteS2: foundSiteS2,
    form: foundForm ? [foundForm.data] : [], // empty array if no items matched
  }
})

const result = populate(merge(siteS1, siteS2, form))
console.log(result)

What am I missing here?

EDIT:

Here is the example code:

var siteS1 = [{
Date: '2021-02-02 11:19',
siteid: 77,
}];


var siteS2 = [{
Date: '2021-02-02 11:19',
siteid: 77,
}];

var form = [{
data: {},
siteid: 77,
},
{
data: {},
siteid: 77,
},
{
data: {},
siteid: 77,
},
{
data: {},
siteid: 77,
},
{
data: {},
siteid: 78,
}];

The expected result is this:

[{
    "siteS1": {
        "Date": "2021-02-02 11:19"
    },
    "siteS2": {
        "Date": "2021-02-02 11:19"
    },
    "form": [{},{},{},{}]
}]

But the current code’s results is this:

[{
    "siteS1": {
        "Date": "2021-02-02 11:19"
    },
    "siteS2": {
        "Date": "2021-02-02 11:19"
    },
    "form": [{}]
}]

as you can see, it only finds 1 of the forms with the siteid of 77 and ignores the rest.

>Solution :

Array.find finds first matching element only, I use another function to find all matching data for the form

const findAll = (siteid, array) => {
    return array.filter(item => item.siteid === siteid).map(({siteid, ...data}) => data);
}
var siteS1 = [{
    Date: '2021-02-02 11:19',
    siteid: 77,
  },
  {
    Date: '2021-02-02 11:19',
    siteid: 76,
  },
  {
    Date: '2021-02-02 11:19',
    siteid: 66,
  },
  {
    Date: '2021-02-02 11:19',
    siteid: 96,
  }
];


var siteS2 = [{
    Date: '2021-02-02 11:19',
    siteid: 77,
  },
  {
    Date: '2021-02-02 11:19',
    siteid: 76,
  },
  {
    Date: '2021-02-02 11:19',
    siteid: 66,
  },
  {
    Date: '2021-02-02 11:19',
    siteid: 96,
  }
];

var form = [{
    data: {},
    siteid: 77,
  },
  {
    data: {},
    siteid: 77,
  },
  {
    data: {},
    siteid: 77,
  },
  {
    data: {},
    siteid: 96,
  }
];

const merge = (...arrayList) => {
  const siteids = arrayList
    .map(array => array.map(item => item.siteid))
    .flat()
  return Array.from(new Set(siteids))
}

const find = (siteid, array) => {
  const found = array.find(item => item.siteid === siteid)
  if (!found) return undefined // returns undefined if item was not found
  const {
    siteid: _,
    ...restFoundData
  } = found // omit `siteid` from found item
  return restFoundData
}

const findAll = (siteid, array) => {
  return array.filter(item => item.siteid === siteid).map(({siteid, ...data}) => data);
}

const populate = (siteids) => siteids.map(siteid => {
  const foundSiteS1 = find(siteid, siteS1)
  const foundSiteS2 = find(siteid, siteS2)
  const foundForm = findAll(siteid, form)
  return {
    siteS1: foundSiteS1,
    siteS2: foundSiteS2,
    form: foundForm, // empty array if no items matched
  }
})

const result = populate(merge(siteS1, siteS2, form))
console.log(result)

Leave a Reply