Siva Pradhan
Siva Pradhan

Reputation: 861

Replace key in an object with value from array of object

Suppose I have an object as,

const emailCount = {'[email protected]':4,'[email protected]':9}

And I have an array of object as,

const emailDetails = [{'emailId': '[email protected]','name':'Alision', 'subject':'hello'},{'emailId':'[email protected]','name':'Hanumant', 'subject':'ola'},
                           {'emailId':'[email protected]','name':'Brian', 'subject':'namaste'},{'emailId':'[email protected]','name':'Alision', 'subject':'hello'}]

There can be multiple entries with same emailId.

So what I want to do is replace key i.e. emailId from emailCount with name from emailDetails.

Name for emailId in emailDetails, irrespective of how many entries will always remain same.

My expected O/P is : {'Alision':4,'Hanumant': 9}

How can I replace my key in emailCount with name in emailDetails' emailId as key?I tried looking solutions but was unable to find aything replated to it. If any one needs any furteher detais please let me.

Upvotes: 2

Views: 124

Answers (5)

Nikhilesh K V
Nikhilesh K V

Reputation: 1480

emailDetails.forEach(function(detail) {
  if(emailCount[detail.emailId]) {
    emailCount[detail.name] = emailCount[detail.emailId];
    delete emailCount[detail.emailId];
  }
 });

A simple solution using a single loop. If a match is found in emailCount object for that emailId, copy that in a new key and delete the email key.

Upvotes: 1

tdy
tdy

Reputation: 41327

If I understand correctly, you only want to replace emailCount's keys, not create another object or do any extra counting.

If so, you can mutate the emailCount object:

const emailCount = {'[email protected]': 4, '[email protected]': 9}
const emailDetails = [{'emailId': '[email protected]', 'name': 'Alision', 'subject': 'hello'}, {'emailId': '[email protected]', 'name': 'Hanumant', 'subject': 'ola'}, {'emailId': '[email protected]', 'name': 'Brian', 'subject': 'namaste'}, {'emailId': '[email protected]', 'name': 'Alision', 'subject': 'hello'}]

for (emailId in emailCount) {
    const name = emailDetails.find(x => x.emailId === emailId).name
    delete Object.assign(emailCount, {[name]: emailCount[emailId]})[emailId]
}

console.log(emailCount)

Upvotes: 1

Dipak Telangre
Dipak Telangre

Reputation: 1993

Basically if you want to group it and count it, You can use Array.reduce

var groupByCount = (arrayData, key) => {
    return arrayData.reduce( (r, a) => {
        r[a[key]] = r[a[key]] || 0 ;
        r[a[key]] ++;
        return r;
    }, Object.create(null));

}

Use

const emailDetails = [{'emailId': '[email protected]','name':'Alision', 'subject':'hello'},{'emailId':'[email protected]','name':'Hanumant', 'subject':'ola'},
                           {'emailId':'[email protected]','name':'Brian', 'subject':'namaste'},{'emailId':'[email protected]','name':'Alision', 'subject':'hello'}]


groupByCount(emailDetails, 'name'); // {Alision: 2, Hanumant: 1, Brian: 1}

groupByCount(emailDetails, 'emailId'); // {[email protected]: 2, [email protected]: 1, [email protected]: 1}
 
groupByCount(emailDetails, 'subject'); // {hello: 2, ola: 1, namaste: 1}

Upvotes: 2

vicovicovico
vicovicovico

Reputation: 507

const output = {};
Object.entries(emailCount).forEach(([key, value]) => {
    output[emailDetails.find(item => item.emailId === key).name] = value;
})

note : no undefined check has been done yet, this code needs to be fine-tuned, but here is the general idea

JSFiddle : https://jsfiddle.net/L0o4x86e/

Upvotes: 1

Chase Ingebritson
Chase Ingebritson

Reputation: 1579

I threw together a quick example with comments that explain what is going on as it's moving through the script.

const emailCount = {'[email protected]':4,'[email protected]':9}

const emailDetails = [
  {'emailId': '[email protected]','name':'Alision', 'subject':'hello'},
  {'emailId':'[email protected]','name':'Hanumant', 'subject':'ola'},
  {'emailId':'[email protected]','name':'Brian', 'subject':'namaste'},
  {'emailId':'[email protected]','name':'Alision', 'subject':'hello'}
]

// Create the object that we're going to store the output in
const output = {}

// Loop through the emailCount object in [[email, count]] format
Object.entries(emailCount)
  .forEach((emailCountEntry) => {
    const [email, count] = emailCountEntry
    
    // Filter through our second input object and return any entries that match the given email
    const selected = emailDetails.filter(details => details.emailId === email)
    
    // If one was found, add it to our output
    if (selected.length) {
      output[selected[0].name] = count
    }
  })
  
console.log(output)

In the future, please try to include anything you've already tried along with your code in the question. It helps to show that you've put in effort in trying to solve your problem before posting it here.

Upvotes: 1

Related Questions