Home > Software engineering >  How to add an object to an array based on its values?
How to add an object to an array based on its values?

Time:07-04

I have an array of objects, it looks like this:

[{
    Rank: 1,
    Speed1: 91,
    Speed2: 457,
    Username: 'monizotic',
    ProfileLink: 'profile_link',
    VerifiedSpeed: null,
    Video: null
}, {
    Rank: 2,
    Speed1: 91,
    Speed2: 457,
    Username: 'Thachtawan',
    ProfileLink: 'profile_link',
    VerifiedSpeed: null,
    Video: null
}, {
    Rank: 3,
    Speed1: 91,
    Speed2: 456,
    Username: 'PassornSibpang',
    ProfileLink: 'profile_link',
    VerifiedSpeed: null,
    Video: null
}, {
    Rank: 4,
    Speed1: 91,
    Speed2: 456,
    Username: 'WasinSoikeeree',
    ProfileLink: 'profile_link',
    VerifiedSpeed: null,
    Video: null
}, {
    Rank: 5,
    Speed1: 91,
    Speed2: 454,
    Username: 'user1055644',
    ProfileLink: 'profile_link',
    VerifiedSpeed: null,
    Video: null
}]

Each object is "1 user". Rank is the user's place in the leaderboard. Each user also has Speed1 and Speed2. Whoever has the highest Speed1 and Speed2 is in the first place. Those who have the lowest ones are on the last place. I hope you understand the meaning. I need to somehow implement a function that would be able to insert a "new user" into this array with objects. An example of such a user:

{
    Rank: null,
    Speed1: 91,
    Speed2: 456,
    Username: 'thaniman',
    ProfileLink: 'profile_link',
    VerifiedSpeed: null,
    Video: null
}

In the object above Rank is null, since it is not yet known. It should change when this user object is in the right place in the array

How can I do that?

CodePudding user response:

Please see the below solution with an O(N) time complexity.

It was made with an assumption that the desired insertion index logic is (user.Speed1 * user.Speed2) < (newUser.Speed1 * newUser.Speed2). Consequently, among all users with identical speeds, the new user will be inserted as the last one.

Noteworthy, though, the users may be not-the-best data structure for this task.

const users = [
 { Rank: 1, Speed1: 91, Speed2: 457, Username: 'monizotic',      ProfileLink: 'profile_link', VerifiedSpeed: null, Video: null },
 { Rank: 2, Speed1: 91, Speed2: 457, Username: 'Thachtawan',     ProfileLink: 'profile_link', VerifiedSpeed: null, Video: null },
 { Rank: 3, Speed1: 91, Speed2: 456, Username: 'PassornSibpang', ProfileLink: 'profile_link', VerifiedSpeed: null, Video: null },
 { Rank: 4, Speed1: 91, Speed2: 456, Username: 'WasinSoikeeree', ProfileLink: 'profile_link', VerifiedSpeed: null, Video: null },
 { Rank: 5, Speed1: 91, Speed2: 454, Username: 'user1055644',    ProfileLink: 'profile_link', VerifiedSpeed: null, Video: null }
];


const insertUser = newUser => {
  const newUserSpeed = newUser.Speed1 * newUser.Speed2;
  let insertIndex = users.findIndex(user => (user.Speed1 * user.Speed2) < newUserSpeed);
      insertIndex = insertIndex >= 0 ? insertIndex : users.length;

  // assign the new user a rank
  newUser.Rank = insertIndex   1; 

  // insert the user
  users.splice(insertIndex, 0, newUser);

  // increment ranks of subsequent users
  users.slice(insertIndex   1).forEach(user => user.Rank  );
};

insertUser({ Rank: null, Speed1: 91, Speed2: 456, Username: 'thaniman', ProfileLink: 'profile_link', VerifiedSpeed: null, Video: null });
console.log(JSON.stringify(users))

CodePudding user response:

It's probably best to do this in stages rather than all at once.

  1. push the new user object into the data array.
  2. map over each user object and calculate the average speed.
  3. sort the returned array by average speed.
  4. map over the sorted array updating the rank for each user based on the object's position in the array.

const data=[{Rank:1,Speed1:91,Speed2:457,Username:"monizotic",ProfileLink:"profile_link",VerifiedSpeed:null,Video:null},{Rank:2,Speed1:91,Speed2:457,Username:"Thachtawan",ProfileLink:"profile_link",VerifiedSpeed:null,Video:null},{Rank:3,Speed1:91,Speed2:456,Username:"PassornSibpang",ProfileLink:"profile_link",VerifiedSpeed:null,Video:null},{Rank:4,Speed1:91,Speed2:456,Username:"WasinSoikeeree",ProfileLink:"profile_link",VerifiedSpeed:null,Video:null},{Rank:5,Speed1:91,Speed2:454,Username:"user1055644",ProfileLink:"profile_link",VerifiedSpeed:null,Video:null}];
const newUser={Rank:null,Speed1:91,Speed2:456,Username:"thaniman",ProfileLink:"profile_link",VerifiedSpeed:null,Video:null};

// `push` the new user into the array
data.push(newUser);

// `map` over the array to create some average speeds
const average = data.map(obj => {
  return { ...obj, Avg: (obj.Speed1   obj.Speed2) / 2 };
});

// `sort` the array by those averages
average.sort((a, b) => b.Avg - a.Avg);

// `map` over the objects and update the rank
// based on the object's position in the array
const final = average.map((obj, i) => {
  const { Rank, Avg, ...rest } = obj;
  return { ...rest, Rank: i   1 };
});

console.log(final);

  • Related