0

I've got the following array of objects:

let arr = [
    {
        status: 'Approved',
        domain: 'random.com',
        refID: '5005w1X4wL7:ref'
    },
    {
        status: 'Approved',
        domain: 'random123.com',
        refID: '5005w1X4wL7:ref'
    },
    {
        status: 'Approved',
        domain: 'helloworld.com',
        refID: '5005w1X4wL7'
    },
    {
        status: 'Approved',
        domain: 'helloworld123.com',
        refID: '5005w1X4wL7'
    }
]

Sorry, I am new to coding but I need to sort or filter through this array to find matching refID's and create new array of objects. Please see an example of the output I am looking for:

let newArr = [
  {
    status: 'Approved',
    domain: ['random.com','random123.com'],
    refID: '5005w1X4wL7:ref'
  },
  {
    status: 'Approved',
    domain: ['hellworld.com','helloworld123.com'],
    refID: '5005w1X4wL7'
  }
]
Varit J Patel
  • 3,497
  • 1
  • 13
  • 21
  • Welcome to SO! What have you done so far to achieve it. please post it. – Varit J Patel Feb 28 '20 at 01:30
  • 3
    I'd suggest looking at `Array.prototype.reduce` or `Array.prototype.forEach`, or consider using a `Map` indexed by `refID`. – fubar Feb 28 '20 at 01:35
  • Please take a look at [how to ask a question](https://stackoverflow.com/help/minimal-reproducible-example). You always want to show what you have tried. Odds are that you are really close and you only need a minor tweak. Remember we don't get paid and this is an archive - duplicate questions aren't allowed. Make it easy for us to help you. :) – Rodger Feb 28 '20 at 01:44
  • You can use [this](https://stackoverflow.com/a/60444325/5648954) with `groupAndMerge(arr, 'refID', 'domain')` (second or third snippet) – Nick Parsons Feb 28 '20 at 02:58

2 Answers2

0

I would create a stackDomainsByRef function that uses a .forEach loop to loop around the arr and a regular loop on the inside to break out of after adding the domain to an existing Object in the output Array and setting a variable that was false to true at each step of the forEach loop. If the variable remains false a new Object is added to the output Array. The output Array is of course returned.

const arr = [
    {
        status: 'Approved',
        domain: 'random.com',
        refID: '5005w1X4wL7:ref'
    },
    {
        status: 'Approved',
        domain: 'random123.com',
        refID: '5005w1X4wL7:ref'
    },
    {
        status: 'Approved',
        domain: 'helloworld.com',
        refID: '5005w1X4wL7'
    },
    {
        status: 'Approved',
        domain: 'helloworld123.com',
        refID: '5005w1X4wL7'
    }
];
function stackDomainsByRef(array){
  const a = [];
  array.forEach(o=>{
    let w = false;
    for(let i=0,v,l=a.length; i<l; i++){
      v = a[i];
      if(o.refID === v.refID){
        v.domains.push(o.domain); w = true;
        break;
      }
    };
    if(w === false){
      a.push({status:o.status, domains:[o.domain], refID:o.refID});
    }
  });
  return a;
}
const newArr = stackDomainsByRef(arr);
console.log(newArr);
StackSlave
  • 10,613
  • 2
  • 18
  • 35
0

Here is an approach using reduce.

const arr = [{
    status: 'Approved',
    domain: 'random.com',
    refID: '5005w1X4wL7:ref'
  },
  {
    status: 'Approved',
    domain: 'random123.com',
    refID: '5005w1X4wL7:ref'
  },
  {
    status: 'Approved',
    domain: 'helloworld.com',
    refID: '5005w1X4wL7'
  },
  {
    status: 'Approved',
    domain: 'helloworld123.com',
    refID: '5005w1X4wL7'
  }
];

result = arr.reduce((acl, v, idx, self) => {
  acl[v['refID']] = acl[v['refID']] || v;
  var domain = acl[v['refID']]['domain'];

  if (domain.indexOf(v['domain']) < 0) {
    acl[v['refID']]['domain'] = domain + "," + v['domain'];
  }

  return acl;
}, {});
result = Object.values(result).map((v) => {
  v['domain'] = v.domain.split(",");
  return v;
});

console.log(result);
DevZer0
  • 13,433
  • 7
  • 27
  • 51