2

I have such a case:

const ids = {
// id: parentId
  "2": "1",
  "3": "1"
}

const input = [
  {
    id: "1",
    data: [1],
  },
   {
     id: "2",
     data: [2]
   },
   {
     id: "3",
     data: [3]
   },
   {
     id: "4",
     data: [4]
   }
]

const output = [
  {
    id: "1",
    data: [1,2,3]
  },
  {
    id: "4",
    data: [4]
  }
]

With this ids I wanted to create some kind of config, which will determine which object in input array should have merged data (if there is no id-parentId pair defined, it should stay as it is). I belive code above is better explanation than this story. I tried with some mappings but without any nice result. This 'ids' array is an example, maybe there is a better way to define it so it will simplify the case? What do you think? I will be grateful for any hint

2
  • 1
    The ids seem to be hierarchical but the output is not. Why not just have mergeIds = [[1,2, 3], ...]? Commented Jun 24, 2022 at 19:08
  • you can't use map() if the output is a different size from the input. Commented Jun 24, 2022 at 19:11

5 Answers 5

2

You can use reduce(). Create the output first as an object that uses id as the key. You can convert it to an array at the end with Object.values().

const ids = {
  // id: parentId
  "2": "1",
  "3": "1"
}

const input = [{
    id: "1",
    data: [1],
  },
  {
    id: "2",
    data: [2]
  },
  {
    id: "3",
    data: [3]
  },
  {
    id: "4",
    data: [4]
  }
]

const output = Object.values(input.reduce((acc, {
  id,
  data
}) => {
  if (id in ids) { // replace id with parent
    id = ids[id];
  }
  if (id in acc) {
    acc[id].data = acc[id].data.concat(data);
  } else {
    acc[id] = {
      id,
      data};
  }
  return acc;
}, {}));

console.log(output);

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

Comments

1

You could take the references for same groups.

const
    ids = { 2: "1", 3: "1" },
    input = [{ id: "1", data: [1] }, { id: "2", data: [2] }, { id: "3", data: [3] }, { id: "4", data: [4] }],
    output = Object.values(input.reduce((r, { id, data }) => {
        id = ids[id] ?? id;
        (r[id] ??= { id, data: [] }).data.push(...data);
        return r;
    }, {}));

console.log(output);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Comments

1

You can try to cycle the input and modifying it in place, something like this should work:

const input = [
  {
    id: '1',
    data: [1]
  },
  {
    id: '2',
    data: [2]
  },
  {
    id: '3',
    data: [3]
  },
  {
    id: '4',
    data: [4]
  }
]

const config = {
  2: '1',
  3: '1'
}

const merge = ({ input, config } = {}) => {
  for (const [childId, parentId] of Object.entries(config)) {
    const childIndex = input.findIndex(i => i.id == childId)
    const parent = input.find(i => i.id == parentId)
    parent.data.push(...input[childIndex].data)
    input.splice(childIndex, 1)
  }

  return input
}

console.log(merge({ input, config }))

Comments

0

you could do it like this:

let ids = { 2: "1", 3: "1" }
let input = [{ id: "1", data: [1] }, { id: "2", data: [2] }, { id: "3", data: [3] }, { id: "4", data: [4] }];
let keys = Object.keys(ids);
let objs = input.slice();//in order to not mutate the source input
const output = objs.map(currObj=>{
    let currId = currObj.id;
    if(keys.includes(currId)){
        let changeObj = objs.find(obj=>obj.id==ids[currId])
        changeObj.data.push(...currObj.data)
    }
    return currObj
})
console.log(output);

NOTE: I used slice() in order to not mutate the source input

Comments

0

You can use Array#reduce, Object.entries and Array#map methods as follows:

const ids = { "2": "1", "3": "1" },
      input = [ { id: "1", data: [1], }, { id: "2", data: [2] }, { id: "3", data: [3] }, { id: "4", data: [4] } ],

output = Object.entries(
    input.reduce(
        (acc,{id,data}) =>
        ids[id] ?
        ({...acc,[ids[id]]:[...(acc[ids[id]] || []),...data]}) :
        ({...acc,[id]:[...(acc[id] || []), ...data]}),{}
    )
)
.map(([id,data]) => ({id,data}));

console.log( output );
//OUTPUT: [{"id":"1","data":[1,2,3]},{"id":"4","data":[4]}]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.