User99
User99

Reputation: 129

Comparing object value with others in same array

I have array like this.

[{first_name: "john", age: "30", institution: {id: 1, name: "inst1"}},
 {first_name: "john", age: "30", institution: {id: 2, name: "inst2"}},
 {first_name: "john", age: "30", institution: {id: 3, name: "inst3"}}]

I want to check if values are same except institution then i want to generate a array like this

[{first_name: "john", age: "30", institution:{name: "inst1, inst2, inst3"}}]

Upvotes: 1

Views: 143

Answers (7)

sney2002
sney2002

Reputation: 896

you can generate a key combining the attributes first_name and age, and use them in a Map Object then convert the result back to an array

const items = [
    {first_name: "john", age: "30", institution: {id: 1, name: "inst1"}},
    {first_name: "john", age: "30", institution: {id: 2, name: "inst2"}},
    {first_name: "john", age: "30", institution: {id: 3, name: "inst3"}}];

const key = item => `${item.first_name}:${item.age}`;

const unique = new Map(items.map(item => [key(item), item]))
const result = Array.from(unique.values())

Upvotes: 0

Avinash Kumar
Avinash Kumar

Reputation: 19

Please check this code-

let a = [{ first_name: "john", age: "30", institution: { id: 1, name: "inst1" } },
{ first_name: "john", age: "30", institution: { id: 2, name: "inst2" } },
{ first_name: "mohan", age: "20", institution: { id: 2, name: "inst2" } },
{ first_name: "john", age: "30", institution: { id: 3, name: "inst3" } }];

let b = [];
for (var i = 0; i < a.length; i++) {
    if (b.length != 0) {

        let j_val = '';
        let flag = false;

        for (let j = 0; j < b.length; j++) {
            if ((a[i].first_name == b[j].first_name) && (a[i].age == b[j].age)) {
                j_val = j;
                flag = true;
            } else {

            }

        }
        let cc = a[i].institution.name;
        if (flag) {
            b[j_val].institution.name = b[j_val].institution.name + "," + cc;
        } else {
            b.push({ first_name: a[i].first_name, age: a[i].age, institution: { name: a[i].institution.name } });
        }
    } else {
        b.push({ first_name: a[i].first_name, age: a[i].age, institution: { name: a[i].institution.name } });
    }

}

console.log(b)

Upvotes: 0

Mohammad Oftadeh
Mohammad Oftadeh

Reputation: 1449

if you use React.js

you can try this:

App.js

// App.js

import React from "react";
import { addItemToUser } from "./utiles";

export default class App extends React.Component {
  state = {
    users: [
      { first_name: "john", age: "30", institution: { id: 1, name: "inst1" } },
      { first_name: "mike", age: "20", institution: { id: 2, name: "inst2" } },
      { first_name: "ali", age: "40", institution: { id: 3, name: "inst3" } }
    ]
  };

  render() {
    const newUser = {
      first_name: "john",
      age: "30",
      institution: { id: 1, name: "inst2" }
    };
    const userList = addItemToUser(this.state.users, newUser);
    console.log(userList);
    return (
      <div className="App">please check your console</div>
    );
  }
}

utiles.js

// utiles.js

export const addItemToUser = (users, userItemToAdd) => {
  const existingUserItem = users.find(
    user => user.first_name === userItemToAdd.first_name
  );

  if (existingUserItem) {
    return users.map(user =>
      user.first_name === userItemToAdd.first_name
        ? { ...user, institution: { name: user.institution.name + ', ' + userItemToAdd.institution.name } }
        : user
    );
  }

  return [...users, { ...userItemToAdd }];
};

Upvotes: 0

Ben Aston
Ben Aston

Reputation: 55729

This might help.

const data = [{first_name: "john", age: "30", institution: {id: 1, name: "inst1"}},
              {first_name: "john", age: "30", institution: {id: 2, name: "inst2"}},
              {first_name: "john", age: "30", institution: {id: 3, name: "inst3"}}]

console.log(
    Object.values(
        data.reduce((p,{ institution: { name }, ...r }, _, __, k = r) =>
            ((p[k] ? (p[k].institution.name += `, ${name}`) 
                   : p[k] = ({ ...r, institution: { name }  })), p),{})))

Upvotes: 0

qiAlex
qiAlex

Reputation: 4346

you can try this

const arr = [{first_name: "john", age: "30", institution: {id: 1, name: "inst1"}},
 {first_name: "john", age: "30", institution: {id: 2, name: "inst2"}},
 {first_name: "john", age: "30", institution: {id: 3, name: "inst3"}}];

const result = arr.reduce((acc, item) => {
  const itemInAcc = acc.find(itemAcc => itemAcc.first_name === item.first_name && itemAcc.age === item.age);
  
  if (!itemInAcc) {
    acc.push({...item, institution: {name: item.institution.name}})
  } else {
    itemInAcc.institution.name = [itemInAcc.institution.name, item.institution.name].join(`, `)
  }
  return acc;
}, []);

console.log(result); // [{first_name: "john", age: "30", institution: {name: "inst1, inst2, inst3"}}]

Upvotes: 0

Ashish
Ashish

Reputation: 410

Please use The below Code .

let obj = [{
    first_name: "john",
    age: "30",
    institution: {
      id: 1,
      name: "inst1"
    }
  },
  {
    first_name: "john",
    age: "30",
    institution: {
      id: 2,
      name: "inst2"
    }
  },
  {
    first_name: "john",
    age: "30",
    institution: {
      id: 3,
      name: "inst3"
    }
  }
]
let newObj = []

let isSame = true;
let obj1 = {}
let obj2 = {}
obj.forEach((o, i) => {

  if (i + 1 < obj.length) {
    obj1 = {
      fn: obj[i].first_name,
      age: obj[i].age
    }
    obj2 = {
      fn: obj[i + 1].first_name,
      age: obj[i + 1].age
    }
    if (JSON.stringify(obj1) !== JSON.stringify(obj2) ){
    	isSame = false;
    }
  }

})

if(isSame){
let anotherobj = {}
	let fn = obj[0].first_name
  let age = obj[0].age;
  let instiValue=''
  obj.forEach(o=>{
  	instiValue = instiValue + o.institution.name + ", ";
  })
  anotherobj.first_name = fn;
  anotherobj.age = age;
  anotherobj.institution = instiValue;
  
  newObj.push(anotherobj);
}

console.log(newObj)

Upvotes: 0

evolon
evolon

Reputation: 1586

What you want to do is some sort of grouping followed by reduce. es6 does not provide groupBy function out of the box. But you can use reduce to achieve the same behavior.

Steps

Source Array --> Group By Person --> Join the institution names

Implemented Solution

In your case:

const arr = [{first_name: "john", age: "30", institution: {id: 1, name: "inst1"}},
 {first_name: "john", age: "30", institution: {id: 2, name: "inst2"}},
 {first_name: "john", age: "30", institution: {id: 3, name: "inst3"}}];


const result = arr.reduce((ac, person) => {
  // check for the existing person in the accumulator
  const existingRecord = ac.find(existingPerson => existingPerson.first_name === person.first_name)

  // if. exists, concatenate the institution
  if (existingRecord) {
    existingRecord.institution += `, ${person.institution.name}`;
    return ac;
  // otherwise, add this as a new person
  } else {
    return [...ac, {
      first_name: person.first_name,
      age: person.age,
      institution: person.institution.name
    }]
  }
}, []);

More general approach to implement a group by:

Most efficient method to groupby on an array of objects

You can also use Lodash which provides more options

Upvotes: 1

Related Questions