how to loop through nested objects and push fields after comparing them in javascript/es6

Viewed 599

I have the following 3 items from the structure of data below:

how

  • Let's assume that group has three fields: id, name, accountNumber and because I have three items, two of them have the same accountNumber.

What i want to do

I want to write a function with javascript/es6 to loop through these objects, check the id and accountNumber in group and push that in a new array of objects named results. (If any id contains the same accountnumber it should not be pushed to the new array below)

# new array 
# results = [
{
    id: 1,
    accountNumber: 2289,
  },
  {
    id: 2,
    accountNumber: 9920,
  },
]

Because of my background with python i am struggling to accomplish this. any help would be very helpful.

5 Answers

Assuming all other data object properties are irrelevant, and I correctly represented your data (the image is cropped):

const data = [
  {group: {id: 1, name:"name1", accountNumber: 1234}, plan:{}, plan_account:{}, plan_benefits:{}},
  {group: {id: 2, name:"name2", accountNumber: 1235}, plan:{}, plan_account:{}, plan_benefits:{}},
  {group: {id: 3, name:"name3", accountNumber: 1234}, plan:{}, plan_account:{}, plan_benefits:{}},
  {group: {id: 4, name:"name4", accountNumber: 1236}, plan:{}, plan_account:{}, plan_benefits:{}},
  {group: {id: 5, name:"name5", accountNumber: 1237}, plan:{}, plan_account:{}, plan_benefits:{}},
]

const result = data.reduce((result, obj) => { 
    if(result.some(ele => ele.accountNumber === obj.group.accountNumber)) return result; 
    result.push({id: obj.group.id, accountNumber: obj.group.accountNumber});
    return result;
}, []);

//will filter out id 3 since it has same accountNumber as id 1
console.log(result)

This example should give you an idea about how to filter same account numbers

data=[{id:2, name:"foo", accountNumber:20209393},{id:2, name:"bar", accountNumber:2020559393},{id:2, name:"foo", accountNumber:20209393}]

result=data.reduce((acc,curr)=>{
  if(acc.length==0) {acc.push(curr)}
  else {
    acc.some(o => {
     if(o.accountNumber==curr.accountNumber){
      return acc
     }
     else acc.push(curr)
  })

}
  return acc
},[])
console.log(result)

You can actually achieve that a bit more concise by using a Map.

by design, a Map only has one value per key thus we can index by accountNumber which will be faster to check for reappearances.

Also, the Map.set() returns the whole Map, which comes in handy when used in Array.reduce() functions because we always have to return the accumulator within such.

The same could be achieved using a dictionary (Object) - see the second snippet - but a dictionary doesn't come as handy as a Map when used in Array.reduce() functions.

Using a Map:

const data = [
  {group: {id: 1, name:"name1", accountNumber: 1234}, plan:{}, plan_account:{}, plan_benefits:{}},
  {group: {id: 2, name:"name2", accountNumber: 1235}, plan:{}, plan_account:{}, plan_benefits:{}},
  {group: {id: 3, name:"name3", accountNumber: 1234}, plan:{}, plan_account:{}, plan_benefits:{}},
  {group: {id: 4, name:"name4", accountNumber: 1236}, plan:{}, plan_account:{}, plan_benefits:{}},
  {group: {id: 5, name:"name5", accountNumber: 1237}, plan:{}, plan_account:{}, plan_benefits:{}},
]
const exists = (result, obj) => result.get(obj.group.accountNumber);
const result = data.reduce((result, obj) => !exists(result, obj) ? result.set(obj.group.accountNumber, {id: obj.group.id, accountNumber: obj.group.accountNumber}) : result, new Map())
console.log([...result.values()])

Using a dictionary:

const data = [
  {group: {id: 1, name:"name1", accountNumber: 1234}, plan:{}, plan_account:{}, plan_benefits:{}},
  {group: {id: 2, name:"name2", accountNumber: 1235}, plan:{}, plan_account:{}, plan_benefits:{}},
  {group: {id: 3, name:"name3", accountNumber: 1234}, plan:{}, plan_account:{}, plan_benefits:{}},
  {group: {id: 4, name:"name4", accountNumber: 1236}, plan:{}, plan_account:{}, plan_benefits:{}},
  {group: {id: 5, name:"name5", accountNumber: 1237}, plan:{}, plan_account:{}, plan_benefits:{}},
]

const exists = (result, obj) => !!result[obj.group.accountNumber];
const result = data.reduce((result, obj) => {
  result[obj.group.accountNumber] = !exists(result, obj) ? {id: obj.group.id, accountNumber: obj.group.accountNumber} : result[obj.group.accountNumber];
  return result;
}, {});
console.log(Object.values(result))

const data = [
   {group: {id: 1, name:"name1", accountNumber: 1234}},
   {group: {id: 2, name:"name2", accountNumber: 5678}},
   {group: {id: 3, name:"name3", accountNumber: 9101}},
   {group: {id: 4, name:"name4", accountNumber: 1213}},
   {group: {id: 5, name:"name5", accountNumber: 1415}},
]

const result = []

data.map(v => {
   const {id} = v.group;
   const {accountNumber} = v.group
   result.push({id, accountNumber})
})

console.log(result)

Or for a one-liner

const data = [{
    group: {
      id: 1,
      name: "name1",
      accountNumber: 1234
    }
  },
  {
    group: {
      id: 2,
      name: "name2",
      accountNumber: 5678
    }
  },
  {
    group: {
      id: 3,
      name: "name3",
      accountNumber: 9101
    }
  },
  {
    group: {
      id: 4,
      name: "name4",
      accountNumber: 1213
    }
  },
  {
    group: {
      id: 5,
      name: "name5",
      accountNumber: 1415
    }
  },
]

const result = []

data.map(v => result.push({
  id: v.group.id,
  accountNumber: v.group.accountNumber
}))

console.log(result)

You could also do without the whole pushing to an array part like this: return the result of a filter on the array. The filter will return only the elements for which the index is the first index of the element with the same account number:

const data = [
  {group: {id: 1, name:"name1", accountNumber: 1234}, plan:{}, plan_account:{}, plan_benefits:{}},
  {group: {id: 2, name:"name2", accountNumber: 1235}, plan:{}, plan_account:{}, plan_benefits:{}},
  {group: {id: 3, name:"name3", accountNumber: 1234}, plan:{}, plan_account:{}, plan_benefits:{}},
  {group: {id: 4, name:"name4", accountNumber: 1236}, plan:{}, plan_account:{}, plan_benefits:{}},
  {group: {id: 5, name:"name5", accountNumber: 1237}, plan:{}, plan_account:{}, plan_benefits:{}},
]

const result =
data.filter((element, index, array) => index == array.findIndex((elm)=>
element.group.accountNumber == elm.group.accountNumber));

console.log(result);
Related