0

can you help me with this problem with js\react? I'm trying to manage 2 arrays due to obtain a new object based on their shared attribute (Array A: "id" and Array B: "parent")

I think isn't hard but I'm struggling to do it atm :(

Array A

[{
  "id": "606f1a2bebb5fb53804dd3d5",
  "name": "cc",
}, {
  "id": "606f1a30cfe84430c41dce88",
  "name": "bb",
}, {
  "id": "606f1a4ed2ff554e4ea11b82",
  "name": "ff",
}]

Array B

[{
  "id": "3344",
  "color": "pink",
  "parent": "606f1a2bebb5fb53804dd3d5",
}, {
  "id": "3453",
  "color": "blue",
  "parent": "606f1a30cfe84430c41dce88",
}, {
  "id": "3331",
  "color": "yellow",
  "parent": "606f1a4ed2ff554e4ea11b82",
}, {
  "id": "4442",
  "color": "black",
  "parent": "606f1a30cfe84430c41dce88",
}]

I want merge these two arrays and create a new one where the array B objects are split by "id" of array A.

Something like this:

[{
  "606f1a2bebb5fb53804dd3d5": [{
    "id": "3344",
    "color": "pink",
    "parent": "606f1a2bebb5fb53804dd3d5",
  }]
}, {
  "606f1a30cfe84430c41dce88": [{
    "id": "3453",
    "color": "blue",
    "parent": "606f1a30cfe84430c41dce88",
  }, {
    "id": "4442",
    "color": "black",
    "parent": "606f1a30cfe84430c41dce88",
  }]
}, {
  "606f1a4ed2ff554e4ea11b82": [{
    "id": "3331",
    "color": "yellow",
    "parent": "606f1a4ed2ff554e4ea11b82",
  }]
}]

Thanks very much guys

Mr. Polywhirl
  • 42,981
  • 12
  • 84
  • 132
sedprc
  • 33
  • 7
  • Based on your mocked output, I assume you want an array of object where there only key is the ID? Why not store an object? Can you make sure you expected output is in the correct JSON format? Looks like you are just grouping the items in the B array by their parent id. Where does the A array come into play here? – Mr. Polywhirl May 11 '21 at 12:48
  • What's the relevance of `A` for the end result? You get the same output if you only have `B` and group it by `parent` – Andreas May 11 '21 at 12:51

5 Answers5

1

You just need array b for grouping and another object for keeping track of the max key inside of a group.

const
    data = [{ id: "3344", color: "pink", parent: "606f1a2bebb5fb53804dd3d5" }, { id: "3453", color: "blue", parent: "606f1a30cfe84430c41dce88" }, { id: "3331", color: "yellow", parent: "606f1a4ed2ff554e4ea11b82" }, { id: "4442", color: "black", parent: "606f1a30cfe84430c41dce88" }],
    max = {},
    result = data.reduce((r, o) => {
        max[o.parent] = (max[o.parent] || 0) + 1;
        (r[o.parent] ??= {})[max[o.parent]] = o;
        return r;
    }, {});

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
  • And yet another _"group by"_ answer instead of a close vote... – Andreas May 11 '21 at 12:53
  • Why are there "numeric" properties when OP ask for an array? – Andreas May 11 '21 at 12:55
  • actually they are gone (after edit from [Mr. Polywhirl](https://stackoverflow.com/posts/67486936/revisions)). now it is just another grouping question ... – Nina Scholz May 11 '21 at 12:56
  • Imho even before the edit this has to be closed as dupe, or as "needs details" as this doesn't show any effort. But I understand... All that lovely reputation (although you already got enough in the dupe target...) – Andreas May 11 '21 at 12:59
0

I think you can loop through the items and then find the parent

let arrayC = [];
arrayB.forEach(item => {
    let parent = array1.find(e => e.id === item.parent);
    // do something here to combine it into one object
    // then arrayC.push(newItem);
});
Robyn
  • 161
  • 1
  • 8
0

https://codesandbox.io/s/boring-snowflake-brksj?file=/src/index.js

const result = arrayA.reduce((acc, arrayAItem) => {
  return {
    ...acc,
    [arrayAItem.id]: arrayB.filter(
      (arrayBItem) => arrayBItem.parent === arrayAItem.id
    )
  };
}, {});
}]
Oro
  • 2,250
  • 1
  • 6
  • 22
0

You can do this with map and filter functions of array.

const newArray = array1.map(array1Item => {
      return { [array1Item.id]: array2.filter(array2Item => array2Item.parent === array1Item.id)}
    })
Priyank Kachhela
  • 2,517
  • 8
  • 16
0

Based on the two arrays that you have, I assume that they are only linked by their "parent" ids. If this is the case, you can reduce the B array using the A array as an accumulator.

const a = [
  { "id": "606f1a2bebb5fb53804dd3d5" , "name": "cc" },
  { "id": "606f1a30cfe84430c41dce88" , "name": "bb" },
  { "id": "606f1a4ed2ff554e4ea11b82" , "name": "ff" },
];

const b = [
  { "id": "3344" , "color": "pink"   , "parent": "606f1a2bebb5fb53804dd3d5" },
  { "id": "3453" , "color": "blue"   , "parent": "606f1a30cfe84430c41dce88" },
  { "id": "3331" , "color": "yellow" , "parent": "606f1a4ed2ff554e4ea11b82" },
  { "id": "4442" , "color": "black"  , "parent": "606f1a30cfe84430c41dce88" },
];

const c = Object
  .entries(b.reduce((acc, { id, color, parent }) =>
    ({ ...acc, [parent]: {
      ...acc[parent],
      colors: [...acc[parent].colors, { id, color } ]
    }}),
    Object.fromEntries(a.map(({ id, name }) =>
      [ id, { name, colors: [] } ]))))
  .map(([ id, value ]) => value);

console.log(c);
.as-console-wrapper { top: 0; max-height: 100% !important; }
Mr. Polywhirl
  • 42,981
  • 12
  • 84
  • 132