简体   繁体   中英

Sort a nested array of object when index is a key in JavaScript

I am trying to sort nested array of objects, based off the key hours. The reason I am setting the index as userId, is that I want to be able to do highScoreList[userId] at a later time to grab the selected user information.

[
 '587665723162626': { userId: '587665723162626', hours: 0, lastHours: 0 },
 '120156769943556': { userId: '120156769943556', hours: 0, lastHours: 0 },
 '773193626386432': { userId: '773193626386432', hours: 10, lastHours: 2 }
]
    let highScoreList = [];
    //data is inserted via another function from mongoDB and below is how I inserted into the array.
    const updateHighScoreCache = (userId, hours, lastHours) =>{
        highScoreList[userId] = { userId, hours, lastHours };
    }
            
    function compare(a, b) {
        if(a.hours > b.hours) return 1;
        if(b.hours > a.hours) return -1;
        return 0;
    }
    highScoreList.sort(compare)

I have tried changing the if statement in the compare function to the following and the array did not change at all still:

   if(highScoreList[a].hours > highScoreList[b].hours) return 1;
   if(highScoreList[b].hours > highScoreList[a].hours) return -1;

The expected result after sort is:

[
 '773193626386432': { userId: '773193626386432', hours: 10, lastHours: 2 },
 '587665723162626': { userId: '587665723162626', hours: 0, lastHours: 0 },
 '120156769943556': { userId: '120156769943556', hours: 0, lastHours: 0 }
]

But I keep getting the original array.

Your array literal at the top is not valid JS syntax. The code shows where you go wrong.

First you define highScoreList as an array, but then you don't populate the array, but create object properties for it, with:

highScoreList[userId] = { userId, hours, lastHours };

These (non-index) properties are ignored by the typical array methods such as sort . Those methods work on the values stored at the array indexes .

So change this:

highScoreList[userId] = { userId, hours, lastHours };

to this:

highScoreList.push({ userId, hours, lastHours });

If however, the structure is returned to you as a plain object (not an array), like so:

{
  '587665723162626': { userId: '587665723162626', hours: 0, lastHours: 0 },
  '120156769943556': { userId: '120156769943556', hours: 0, lastHours: 0 },
  '773193626386432': { userId: '773193626386432', hours: 10, lastHours: 2 }
}

..then note that plain objects are not really the right tool for sorting . They better serve use cases where you don't care about order. So if you really get an object like this (not an array) and need order, then covert that object to an array first, with:

highScoreList = Object.values(highScoreList);

...and then call .sort

Another remark: your compare function will do the job, but the way it really is done, is as follows:

const compare = (a, b) => a.hours - b.hours;

If you array is:

const highScoreList = [
 { userId: '587665723162626', hours: 0, lastHours: 0 },
 { userId: '120156769943556', hours: 0, lastHours: 0 },
 { userId: '773193626386432', hours: 10, lastHours: 2 }
];

Then this code sorts it DESC:

highScoreList.sort((x,y) => y.hours - x.hours)

Then this code sorts it ASC:

highScoreList.sort((x,y) => x.hours - y.hours)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM