2

I have three arrays like below (I have large data of like 25000, so you may also please advise if this is a good approach for that amount of data):

var arrayScores =    [10, 21, 2, 35, 19, 85, 96, 70,  85,  19, 100, 11, 35, 70, 98, 81, 92];
var arrayGenders =   ['M', 'M', 'F', 'F', 'M', 'M', 'M', 'F',  'F',  'M',  'M', 'F', 'F', 'M', 'M', 'F', 'F'];
var arrayNames =     ['John', 'Fred', 'Jacque', 'Andrea', 'Andrew', 'Jacob', 'Dylan', 'Diana',  'Rahel',  'Raphael',  'Bob', 'Mariam', 'Fatma', 'Ahmed', 'Barack', 'Joyce', 'Taina'];

So I want to sort these arrays ranks by scores (in descending order), then by gender (in ascending order), and lastly by name in (ascending order) as shown below :

1.Bob-100, 2.Barack-98, 3.Dylan-96, 4.Taina-92, 5.Rahel-85, 6.Jacob-85, 7.Joyce-81, 8.Diana-70, 9.Ahmed-70, 10.Andrea-35, 11.Fatma-35, 12.Fred-21, 13.Andrew-19, 14.Raphael-19, 15.Mariam-11, 16.John-10, 17.Jacque-2

Here is my code, but it doesn't provide what I expect as I don't know how to sort it (I'm still a beginner learning JavaScript), Please help!

var arrayScores =    [10, 21, 2, 35, 19, 85, 96, 70,  85,  19, 100, 11, 35, 70, 98, 81, 92];
var arrayGenders =   ['M', 'M', 'F', 'F', 'M', 'M', 'M', 'F',  'F',  'M',  'M', 'F', 'F', 'M', 'M', 'F', 'F'];
var arrayNames =     ['John', 'Fred', 'Jacque', 'Andrea', 'Andrew', 'Jacob', 'Dylan', 'Diana',  'Rahel',  'Raphael',  'Bob', 'Mariam', 'Fatma', 'Ahmed', 'Barack', 'Joyce', 'Taina'];
var rank = 1;
arrayScores.forEach((score, index) => {
  const gender = arrayGenders[index], name = arrayNames[index];
  console.log("Name: "+name+" Gender: "+gender+ " Score: "+score+ " Rank: "+rank);
rank++;
});
Job Gondwe
  • 55
  • 7
  • why not take a single array with another array or object with properties? what if all values are equal? do you want two ranks? or a single one and go on with an increment of two? – Nina Scholz Jan 15 '23 at 10:01
  • @NinaScholz I'm sorry, I'm really a beginner to Javascript, so I don't know how to put that together. Can you please provide an example? And If all values are equal then it should rank them basing on gender and then names. – Job Gondwe Jan 15 '23 at 10:04
  • @NinaScholz So for instance, if we have three names to rank; John (male) has 90, Jane(female) has 90 and Jack (female) has 90. First rank should be Jack, Jane and John as third rank. – Job Gondwe Jan 15 '23 at 10:10

1 Answers1

2

You could build objects and sort in a single run.

This approach takes an object with same names as the final propertiers and creates from the entries an array of objects.

The sorting takes place with the wanted properties. For direct values, like gender, you could take an object for the wanted order. This allows to add more genders and orders.

const
    score = [10, 21, 2, 35, 19, 85, 96, 70, 85, 19, 100, 11, 35, 70, 98, 81, 92],
    gender = ['M', 'M', 'F', 'F', 'M', 'M', 'M', 'F', 'F', 'M', 'M', 'F', 'F', 'M', 'M', 'F', 'F'],
    name = ['John', 'Fred', 'Jacque', 'Andrea', 'Andrew', 'Jacob', 'Dylan', 'Diana', 'Rahel', 'Raphael', 'Bob', 'Mariam', 'Fatma', 'Ahmed', 'Barack', 'Joyce', 'Taina'],
    object = { score, gender, name },
    genders = { F: 1, M: 2 },
    data = Object
        .entries(object)
        .reduce((r, [k, values]) => values.map((v, i) => ({ ...r[i], [k]: v })), [])
        .sort((a, b) =>
            b.score - a.score ||
            genders[a.gender] - genders[b.gender]||
            a.name.localeCompare(b.name)
        );

console.log(data);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
  • This works as expected. Thank you so much. BTW, do you recommend using this same approach for a big data of like 25000 rows or I should transfer the load to server? – Job Gondwe Jan 15 '23 at 10:19
  • why not let take sorting place whare the data is? – Nina Scholz Jan 15 '23 at 10:23
  • just a small hint by using `name` as variable in global context, this variable usually contains the window name, if using undefined or with `var` statement. for using with `let` or `const` declaration, it create a new independent variable. – Nina Scholz Jan 15 '23 at 10:28
  • it seems to not work with big data, I have tried with like 1500 and ranks are so random, doesn't rank as expected. Why is this? – Job Gondwe Jan 15 '23 at 10:58
  • if it is not possible, you could use a grouping (with object by score) for sorting by score and use the subgroubs with shorte subsets for final sorting. – Nina Scholz Jan 15 '23 at 11:05
  • Thank you for that grouping idea, but I have no idea on how to work those subgroups out, can you give an example or maybe editing your answer please? – Job Gondwe Jan 15 '23 at 11:10
  • you could have a look here: https://stackoverflow.com/questions/40774697/how-can-i-group-an-array-of-objects-by-key/40774906#40774906 – Nina Scholz Jan 15 '23 at 11:12
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/251151/discussion-between-nina-scholz-and-job-gondwe). – Nina Scholz Jan 15 '23 at 11:15