Search code examples
javascriptarraysjavascript-objects

How to add an object to an array based on its values?


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?


Solution

  • 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))