heisenberg7584
heisenberg7584

Reputation: 740

Add count value to object with same key values (array of objects)

Hello I have kind of complicated iteration to be done over an array of objects. I have array like this:

[ 
  { name: 'Jacob', lastName: 'Smith', dob: '1995-11-29' },
  { name: 'Jacob', lastName: 'Smith', dob: '1991-08-21' },
  { name: 'Ann', lastName: 'Smith', dob: '1995-11-29' },
  { name: 'Ann', lastName: 'Nansen', dob: '1983-01-01' },
  { name: 'Jacob', lastName: 'Smith', dob: '1985-06-15' },
  { name: 'Jacob', lastName: 'Smith', dob: '1995-11-29' },
  { name: 'Ann', lastName: 'Smith', dob: '2010-11-29' },
]

I would like to add count property to each object that counts objects with same name and surname... So it should be now:

[ 
  { name: 'Jacob', lastName: 'Smith', count: 4 },
  { name: 'Ann', lastName: 'Smith', count: 2 },
  { name: 'Ann', lastName: 'Nansen', count: 1' },
]

Upvotes: 0

Views: 2220

Answers (5)

Francis Leigh
Francis Leigh

Reputation: 1960

You can achieve this by reducing the original Array. As you iterate through the people you can check if they have already been "grouped" using Array.some - if they haven't, push your built person Object to the previously returned Array.

const getInstances = ({ name, lastName }, data) => data.filter(d => d.name === name && d.lastName === lastName).length

const people = [ 
  { name: 'Jacob', lastName: 'Smith', dob: '1995-11-29' },
  { name: 'Jacob', lastName: 'Smith', dob: '1991-08-21' },
  { name: 'Ann', lastName: 'Smith', dob: '1995-11-29' },
  { name: 'Ann', lastName: 'Nansen', dob: '1983-01-01' },
  { name: 'Jacob', lastName: 'Smith', dob: '1985-06-15' },
  { name: 'Jacob', lastName: 'Smith', dob: '1995-11-29' },
  { name: 'Ann', lastName: 'Smith', dob: '2010-11-29' },
]
  
const groupedPeople = people.reduce((group, person, i, people) => {
  const alreadyBeenGrouped = group.some(({ name, lastName }) => name === person.name && lastName === person.lastName)

  if (!alreadyBeenGrouped) {
    group.push({
      name: person.name,
      lastName: person.lastName,
      count: getInstances(person, people)
    })
  }

  return group
}, [])

console.log(groupedPeople)

Upvotes: 0

Garach Ankur
Garach Ankur

Reputation: 58

let arr=[ 
  { name: 'Jacob', lastName: 'Smith', dob: '1995-11-29' },
  { name: 'Jacob', lastName: 'Smith', dob: '1991-08-21' },
  { name: 'Ann', lastName: 'Smith', dob: '1995-11-29' },
  { name: 'Ann', lastName: 'Nansen', dob: '1983-01-01' },
  { name: 'Jacob', lastName: 'Smith', dob: '1985-06-15' },
  { name: 'Jacob', lastName: 'Smith', dob: '1995-11-29' },
  { name: 'Ann', lastName: 'Smith', dob: '2010-11-29' },
];



let outerArr=[];

for(arrValue of arr)
{
  delete arrValue.dob

  let index=outerArr.findIndex(item=> item.name==arrValue.name && 
  item.lastName==arrValue.lastName);

  if(index==-1)
  {
	let arrFind=arr.filter(item=> item.name==arrValue.name && 
    item.lastName==arrValue.lastName)
     arrValue.count=arrFind.length
     outerArr.push(arrValue)
  }

}
	console.log('result',outerArr)

Upvotes: 0

trincot
trincot

Reputation: 350137

You could use JSON.stringify to combine name and last name in a safe way. I like using a Map to group the records with the same keys together:

const data = [{ name: 'Jacob', lastName: 'Smith', dob: '1995-11-29' },{ name: 'Jacob', lastName: 'Smith', dob: '1991-08-21' },{ name: 'Ann', lastName: 'Smith', dob: '1995-11-29' },{ name: 'Ann', lastName: 'Nansen', dob: '1983-01-01' },{ name: 'Jacob', lastName: 'Smith', dob: '1985-06-15' },{ name: 'Jacob', lastName: 'Smith', dob: '1995-11-29' },{ name: 'Ann', lastName: 'Smith', dob: '2010-11-29' }];
const keyed = data.map(o => [JSON.stringify([o.name, o.lastName]), o]);
const map = new Map(keyed.map(([key, {name, lastName}]) => 
                              [key, {name, lastName, count: 0}]));
keyed.forEach(([key, o]) => map.get(key).count++);
const result = Array.from(map.values());

console.log(result);

Upvotes: 0

Nikhil Aggarwal
Nikhil Aggarwal

Reputation: 28445

You can use Array.reduce and Object.values

  • Convert array in an object with key as name and last name combination with value being the resulting object.
  • From the object, get all values as the final result

let arr = [{ name: 'Jacob', lastName: 'Smith', dob: '1995-11-29' },{ name: 'Jacob', lastName: 'Smith', dob: '1991-08-21' },{ name: 'Ann', lastName: 'Smith', dob: '1995-11-29' },{ name: 'Ann', lastName: 'Nansen', dob: '1983-01-01' },{ name: 'Jacob', lastName: 'Smith', dob: '1985-06-15' },{ name: 'Jacob', lastName: 'Smith', dob: '1995-11-29' },{ name: 'Ann', lastName: 'Smith', dob: '2010-11-29' }];

let result = Object.values(arr.reduce((a,{name, lastName}) => {
  let key = `${name}_${lastName}`;
  a[key] = a[key] || {name, lastName, count : 0};
  a[key].count++;
  return a;
}, {}));

console.log(result);

Upvotes: 5

Jonas Wilms
Jonas Wilms

Reputation: 138247

  const hash = [];

  for(const { name, lastName } of persons) {
    const key = name + "/" + lastName;
    if(!hash[key]) hash[key] = {
      name,
      lastName,
      count: 0,
    };

    hash[key].count++;
 }

  const result = Object.values(hash);

Upvotes: 0

Related Questions