Home > database >  how to group and reduce and add elements to objects inside array
how to group and reduce and add elements to objects inside array

Time:12-28

let say I have an array like below

let arr = [
{id:1, s:1, e: 5},
{id:2, s:6, e: 10},
{id:3, s:11, e: 15},
{id:4, s:1, e: 5},
{id:5, s:6, e: 10},
{id:6, s:11, e: 15},
{id:7, s:11, e: 15},
{id:8, s:20, e: 25},
{id:9, s:25, e: 30},
{id:10, s:20, e: 25},
]
  • I have to check duplicate s and e value
  • then on first occurrence object, I need to add dup key to store array of duplicate index value where duplicate element appears.
  • finally i should remove all duplicate object and keep first object with duplicate keys.

expected output should be

[
{id:1, s:1, e: 5, dup: [1,4]},
{id:2, s:6, e: 10, dup: [2,5]},
{id:3, s:11, e: 15, dup: [3,6,7]},
{id:8, s:20, e: 25, dup: [8,10]},
{id:9, s:25, e: 30} // no duplicate then dup should not be added
]

I tried below but no use

const filteredArr = splits.reduce((acc, curr) => {
       let repeat = []
        const obj = acc.find((item) => {
            if (
                item.s === curr.s &&
                item.e === curr.e
            ) {
                repeat.push(item.id)
                repeat.push(curr.id)
                return true
            } else {
                return false
            }
        })
        if (obj) {
            if (!obj.isMulti) {
                obj.dup = repeat
                obj.isMulti = true
            }
            return acc
        }

        acc.push(curr)
        return acc
    }, [])
    return filteredArr

I'm not getting proper logic from where to start! any help or guidance please.

CodePudding user response:

this works but probably it isn't the most performing solution

const arr = [
{id:1, s:1, e: 5},
{id:2, s:6, e: 10},
{id:3, s:11, e: 15},
{id:4, s:1, e: 5},
{id:5, s:6, e: 10},
{id:6, s:11, e: 15},
{id:7, s:11, e: 15},
{id:8, s:20, e: 25},
{id:9, s:25, e: 30},
{id:10, s:20, e: 25},
]

const groupDuplicates = (data) => {

const set = [...new Set(data.map(({s, e}) => JSON.stringify({s,e})))]

return set.map(el => {
 const {s, e} = JSON.parse(el)
 const matching = data.filter(d => d.s === s && d.e === e)
 if(matching.length === 1){
   return {id: matching[0].id, s, e}
 }
 return {
   id: matching[0].id,
   s,
   e,
   dup: matching.map(m => m.id)
 } 
})
}

console.log(groupDuplicates(arr))

CodePudding user response:

You could group with an object and add dup, if necessary and add the actual id to it.

const
    array = [{ id: 1, s: 1, e: 5 }, { id: 2, s: 6, e: 10 }, { id: 3, s: 11, e: 15 }, { id: 4, s: 1, e: 5 }, { id: 5, s: 6, e: 10 }, { id: 6, s: 11, e: 15 }, { id: 7, s: 11, e: 15 }, { id: 8, s: 20, e: 25 }, { id: 9, s: 25, e: 30 }, { id: 10, s: 20, e: 25 }],
    keys = ['s', 'e'],
    getKey = o => keys.map(k => o[k]).join('|'),
    result = Object.values(array.reduce((r, o) => {
        const key = getKey(o);
        if (r[key]) (r[key].dup ??= [r[key].id]).push(o.id);
        else r[key] = { ...o };
        return r;
    }, {}));

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

CodePudding user response:

You can use an object to keep track of repeated ${s}_${e} combinations and get an array from it

let arr = [
  {id:1, s:1, e: 5},
  {id:2, s:6, e: 10},
  {id:3, s:11, e: 15},
  {id:4, s:1, e: 5},
  {id:5, s:6, e: 10},
  {id:6, s:11, e: 15},
  {id:7, s:11, e: 15},
  {id:8, s:20, e: 25},
  {id:9, s:25, e: 30},
  {id:10, s:20, e: 25},
]

const dups = Object.values(arr.reduce((hash, curr) => {
  const {id, s, e} = curr;
  const key = `${s}_${e}`;
  if(key in hash) {
    return (hash[key].dup ??= [hash[key].id]).push(id), hash;
  }
  return hash[key] = {...curr}, hash;
}, {}))
console.log(dups)

  • Related