Home > OS >  Group a list of duplicate Objects without removing duplicate into a map
Group a list of duplicate Objects without removing duplicate into a map

Time:11-03

I have a list of objects in an array. Each object has an email.

The array could have duplicate emails and I want to keep them.

I want to give a number let's say 4 and it should split the emails into groups of 4 emails into a map where the key is like group-1 ... and the value 4 unique emails in each key in this case I will have a map of 5 keys

const emails = [
  {
    userId: 'someuserid',
    email: '[email protected]',
    password: 'password1',
    recovery: '[email protected]'
  },
  {
    userId: 'someuserid',
    email: '[email protected]',
    password: 'password1',
    recovery: '[email protected]'
  },
  {
    userId: 'someuserid',
    email: '[email protected]',
    password: 'password10',
    recovery: '[email protected]'
  },
  {
    userId: 'someuserid',
    email: '[email protected]',
    password: 'password10',
    recovery: '[email protected]'
  },
  {
    userId: 'someuserid',
    email: '[email protected]',
    password: 'password2',
    recovery: '[email protected]'
  },
  {
    userId: 'someuserid',
    email: '[email protected]',
    password: 'password2',
    recovery: '[email protected]'
  },
  {
    userId: 'someuserid',
    email: '[email protected]',
    password: 'password3',
    recovery: '[email protected]'
  },
  {
    userId: 'someuserid',
    email: '[email protected]',
    password: 'password3',
    recovery: '[email protected]'
  },
  {
    userId: 'someuserid',
    email: '[email protected]',
    password: 'password4',
    recovery: '[email protected]'
  },
  {
    userId: 'someuserid',
    email: '[email protected]',
    password: 'password4',
    recovery: '[email protected]'
  },
  {
    userId: 'someuserid',
    email: '[email protected]',
    password: 'password5',
    recovery: '[email protected]'
  },
  {
    userId: 'someuserid',
    email: '[email protected]',
    password: 'password5',
    recovery: '[email protected]'
  },
  {
    userId: 'someuserid',
    email: '[email protected]',
    password: 'password6',
    recovery: '[email protected]'
  },
  {
    userId: 'someuserid',
    email: '[email protected]',
    password: 'password6',
    recovery: '[email protected]'
  },
  {
    userId: 'someuserid',
    email: '[email protected]',
    password: 'password7',
    recovery: '[email protected]'
  },
  {
    userId: 'someuserid',
    email: '[email protected]',
    password: 'password7',
    recovery: '[email protected]'
  },
  {
    userId: 'someuserid',
    email: '[email protected]',
    password: 'password8',
    recovery: '[email protected]'
  },
  {
    userId: 'someuserid',
    email: '[email protected]',
    password: 'password8',
    recovery: '[email protected]'
  },
  {
    userId: 'someuserid',
    email: '[email protected]',
    password: 'password9',
    recovery: '[email protected]'
  },
  {
    userId: 'someuserid',
    email: '[email protected]',
    password: 'password9',
    recovery: '[email protected]'
  }
]

//this is the code i came up with but it's working

const groupsMap = new Map()
let sequence = 0
let profilePrefix = 'none'
let pivotPrefix = 0
for (let index = 0; index < emails.length; index  ) {
  const currentEmail = emails[index]?.email
  const prevEmail = emails[index - 1]?.email
  if (prevEmail && currentEmail === prevEmail) {
    if (
      profilesMap.has(`${prefix}-${pivotPrefix}`) &&
      profilesMap.get(`${prefix}-${pivotPrefix}`).length < mailboxProfileNum &&
      profilesMap
        .get(`${prefix}-${pivotPrefix}`)
        .findIndex((email) => currentEmail === email.email) === -1
    ) {
      profilesMap.get(`${prefix}-${pivotPrefix}`).push(emails[index])
      if (
        profilesMap.get(`${prefix}-${pivotPrefix}`).length === mailboxProfileNum
      ) {
        pivotPrefix  
      }
    } else {
      if (pivotPrefix > 0) {
        const nextPivot = pivotPrefix  
        profilesMap.get(`${prefix}-${nextPivot}`).push(emails[index])
      }
      sequence  
      profilePrefix = `${prefix}-${sequence}`
      profilesMap.set(profilePrefix, [emails[index]])
    }
  } else {
    if (profilesMap.has(`${prefix}-${pivotPrefix}`)) {
      if (
        profilesMap.get(`${prefix}-${pivotPrefix}`).length < mailboxProfileNum
      ) {
        profilesMap.get(`${prefix}-${pivotPrefix}`).push(emails[index])
        if (
          profilesMap.get(`${prefix}-${pivotPrefix}`).length ===
          mailboxProfileNum
        ) {
          pivotPrefix  
        }
      } else {
        sequence  
        profilesMap.set(`${prefix}-${sequence}`, [emails[index]])
      }
    } else {
      sequence  
      pivotPrefix = sequence
      profilePrefix = `${prefix}-${pivotPrefix}`
      profilesMap.set(profilePrefix, [emails[index]])
    }
  }
}


Map(5) {
    'group-1' => [
      {
        userId: 'userid',
        email: '[email protected]',
        password: 'password1',
        recovery: '[email protected]'
      },
      {
        userId: 'userid',
        email: '[email protected]',
        password: 'password2',
        recovery: '[email protected]'
      },
      {
        userId: 'userid',
        email: '[email protected]',
        password: 'password3',
        recovery: '[email protected]'
      },
      {
        userId: 'userid',
        email: '[email protected]',
        password: 'password4',
        recovery: '[email protected]'
      }
    ],
    'group-2' => [
      {
        userId: 'userid',
        email: '[email protected]',
        password: 'password1',
        recovery: '[email protected]'
      },
      {
        userId: 'userid',
        email: '[email protected]',
        password: 'password2',
        recovery: '[email protected]'
      },
      {
        userId: 'userid',
        email: '[email protected]',
        password: 'password3',
        recovery: '[email protected]'
      },
      {
        userId: 'userid',
        email: '[email protected]',
        password: 'password4',
        recovery: '[email protected]'
      }
    ],
    ...
 }

CodePudding user response:

You can save the groups as "buckets", and find the next bucket to put the email in. If no buckets have available spots, create a new bucket with the email.

const emails=[{userId:'someuserid',email:'[email protected]',password:'password1',recovery:'[email protected]'},{userId:'someuserid',email:'[email protected]',password:'password1',recovery:'[email protected]'},{userId:'someuserid',email:'[email protected]',password:'password10',recovery:'[email protected]'},{userId:'someuserid',email:'[email protected]',password:'password10',recovery:'[email protected]'},{userId:'someuserid',email:'[email protected]',password:'password2',recovery:'[email protected]'},{userId:'someuserid',email:'[email protected]',password:'password2',recovery:'[email protected]'},{userId:'someuserid',email:'[email protected]',password:'password3',recovery:'[email protected]'},{userId:'someuserid',email:'[email protected]',password:'password3',recovery:'[email protected]'},{userId:'someuserid',email:'[email protected]',password:'password4',recovery:'[email protected]'},{userId:'someuserid',email:'[email protected]',password:'password4',recovery:'[email protected]'},{userId:'someuserid',email:'[email protected]',password:'password5',recovery:'[email protected]'},{userId:'someuserid',email:'[email protected]',password:'password5',recovery:'[email protected]'},{userId:'someuserid',email:'[email protected]',password:'password6',recovery:'[email protected]'},{userId:'someuserid',email:'[email protected]',password:'password6',recovery:'[email protected]'},{userId:'someuserid',email:'[email protected]',password:'password7',recovery:'[email protected]'},{userId:'someuserid',email:'[email protected]',password:'password7',recovery:'[email protected]'},{userId:'someuserid',email:'[email protected]',password:'password8',recovery:'[email protected]'},{userId:'someuserid',email:'[email protected]',password:'password8',recovery:'[email protected]'},{userId:'someuserid',email:'[email protected]',password:'password9',recovery:'[email protected]'},{userId:'someuserid',email:'[email protected]',password:'password9',recovery:'[email protected]'}]

const buckets = [];

const bucketSize = 4;

emails.forEach((e) => {
    const bucketIndex = buckets
      .map((b, i) => [b, i]) // zip with index
      .filter(([b]) => b.length < bucketSize) // buckets that aren't full
      .find(([b]) => b.every((u) => u.email !== e.email)); // bucket with available spot

    if (bucketIndex === undefined) buckets.push([e]); // create new bucket
    else buckets[bucketIndex[1]].push(e); // push to existing bucket by index
});

// zip with keys and create map
const map = new Map(buckets.map((b, i) => [`group-${i}`, b]));

// Just for display - Maps aren't displayed properly in the output yet
console.log(Object.fromEntries(Array.from(map)));
.as-console-wrapper { max-height: 100% !important }

CodePudding user response:

Not sure But if you want group of unique emails than this will give you 4 object with unique emails.


  • First I am filtering array with unique values of email and than using chunk function, that takes two parameter one the array and second the size of array.
  • The procedure of chunk function is as below, the only thing **missing here is key otherwise you are getting 4 email object of array in chunks.
  • Take an empty array to push array chuncks
  • check if we will have extra chunks or not;
  • if array length's moudle with chunk size is not equal to zero that we have to count the number of rounds
  • if array length's moudle with chunk size is zero than we just need to push array.splice(0,size) till the array size is not equals to zero
  • if we have rounds , than we just need to push array till the rounds are not complete once its compelete we just need to add extra to result by arra.push(0,extra);
  • In other words,push chunks in array till our array's length is not equal to extra and once array length is just as extra add remaining by arra.push(0,extra);

const emails = [{
    userId: 'someuserid',
    email: '[email protected]',
    password: 'password1',
    recovery: '[email protected]'
  },
  {
    userId: 'someuserid',
    email: '[email protected]',
    password: 'password1',
    recovery: '[email protected]'
  },
  {
    userId: 'someuserid',
    email: '[email protected]',
    password: 'password10',
    recovery: '[email protected]'
  },
  {
    userId: 'someuserid',
    email: '[email protected]',
    password: 'password10',
    recovery: '[email protected]'
  },
  {
    userId: 'someuserid',
    email: '[email protected]',
    password: 'password2',
    recovery: '[email protected]'
  },
  {
    userId: 'someuserid',
    email: '[email protected]',
    password: 'password2',
    recovery: '[email protected]'
  },
  {
    userId: 'someuserid',
    email: '[email protected]',
    password: 'password3',
    recovery: '[email protected]'
  },
  {
    userId: 'someuserid',
    email: '[email protected]',
    password: 'password3',
    recovery: '[email protected]'
  },
  {
    userId: 'someuserid',
    email: '[email protected]',
    password: 'password4',
    recovery: '[email protected]'
  },
  {
    userId: 'someuserid',
    email: '[email protected]',
    password: 'password4',
    recovery: '[email protected]'
  },
  {
    userId: 'someuserid',
    email: '[email protected]',
    password: 'password5',
    recovery: '[email protected]'
  },
  {
    userId: 'someuserid',
    email: '[email protected]',
    password: 'password5',
    recovery: '[email protected]'
  },
  {
    userId: 'someuserid',
    email: '[email protected]',
    password: 'password6',
    recovery: '[email protected]'
  },
  {
    userId: 'someuserid',
    email: '[email protected]',
    password: 'password6',
    recovery: '[email protected]'
  },
  {
    userId: 'someuserid',
    email: '[email protected]',
    password: 'password7',
    recovery: '[email protected]'
  },
  {
    userId: 'someuserid',
    email: '[email protected]',
    password: 'password7',
    recovery: '[email protected]'
  },
  {
    userId: 'someuserid',
    email: '[email protected]',
    password: 'password8',
    recovery: '[email protected]'
  },
  {
    userId: 'someuserid',
    email: '[email protected]',
    password: 'password8',
    recovery: '[email protected]'
  },
  {
    userId: 'someuserid',
    email: '[email protected]',
    password: 'password9',
    recovery: '[email protected]'
  },
  {
    userId: 'someuserid',
    email: '[email protected]',
    password: 'password9',
    recovery: '[email protected]'
  }
];
let filterdResult = []; // to store unique email objects
// to filter emails object with unique email
let filterArray = emails.reduce((visitedEmailContainer, currentEmail) => {
  if (!visitedEmailContainer.includes(currentEmail.email)) {
    filterdResult.push(currentEmail);
    visitedEmailContainer.push(currentEmail.email);
    return visitedEmailContainer;
  }
  return visitedEmailContainer;
}, []);

function chunk(array, size) {
  /*
  - Take an empty array to push array chuncks
  - check if we will have extra chunks or not;
  - if array length's moudle with chunk size is not equal to zero that we have to count the number of rounds
  - if array length's moudle with chunk size is zero than we just need to push array.splice(0,size) till the array size is not equals to zero
  - if we have rounds , than we just need to push array till the rounds are not complete once its compelete we just need to add extra to result by arra.push(0,extra); 
  - In other words,push chunks in array till our array's length is not equal to extra and once array length is just as extra add remaining by arra.push(0,extra);
   */
  let result = [];
  let extra = array.length % size;
  if (extra == 0) {
    while (array.length !== 0) {
      result.push(array.splice(0, size));
    }
  } else if (extra) {
    while (array.length != extra) {
      result.push(array.splice(0, size));
    }
    result.push(array.splice(0, extra));
  }
  console.log(result);
  return result;
}
chunk(filterdResult, 4);

  • Related