简体   繁体   中英

Sort JavaScript array of Objects by two properties and given order

I have this JavaScript array of Objects:

data = [
    {'deviation': 57.41, 'provider': "This", 'measure': "median"},
    {'deviation': 49.02, 'provider': "All", 'measure': "median"},
    {'deviation': 199.67, 'provider': "This", 'measure': "third_quartile"},
    {'deviation': 152.31, 'provider': "All", 'measure': "third_quartile"},
    {'deviation': 41.48, 'provider': "This", 'measure': "first_quartile"},
    {'deviation': -1.07, 'provider': "All", 'measure': "first_quartile"}
]

and I would like to sort it both by 'provider' (the three "This" before the three "All") and by 'measure' (first quartile, median, third quartile), so the resulting array will look like:

data = [
    {'deviation': 41.48, 'provider': "This", 'measure': "first_quartile"},
    {'deviation': 57.41, 'provider': "This", 'measure': "median"},
    {'deviation': 199.67, 'provider': "This", 'measure': "third_quartile"},
    {'deviation': -1.07, 'provider': "All", 'measure': "first_quartile"}
    {'deviation': 49.02, 'provider': "All", 'measure': "median"},
    {'deviation': 152.31, 'provider': "All", 'measure': "third_quartile"},       
]

I have written a function as an argument to .sort() , and it does return the array sorted by 'provider', but then when I feed it into the same function with measure as an argument (thankfully, first_quartile, median, third_quartile are already alphabetically sorted the way I want them) - the sorting gets broken. How can I go about doing it?

EDIT The functions I have been using:

var compare_prv = function(a,b) {
  if (a.provider < b.provider){
    return 1;
  }
  return 0;
}

var compare_meas = function(a,b) {
  if (a.measure < b.measure){
    return -1;
  }
  return 0;
}

It sounds like you are doing:

data.sort(function(a, b) {
    //sort by provider
});

data.sort(function(a, b) {
    //sort by measure
});

But what you want to do is:

data.sort(function(a, b) {
    //sort by provider, but if they are equal, sort by measure
});

So something like

data.sort(function(a, b) {
    if (a.provider === b.provider) {
        return a.measure.localeCompare(b.measure);
    }
    return b.provider.localeCompare(a.provider);
});

You could chain the sorting criteria with logical OR || .

For a set of strings with a defined order, you could use an object for getting the wanted order.

 { first_quartile: 1, median: 2, third_quartile: 3 } 

This lets you sort some item, if not in the order list ssort to start with default zero or to bottom with a huge value like Infinity .

In this case the pattern looks like

 (order[a.measure] || 0) - (order[a.measure] || 0) // to top (order[a.measure] || Infinify ) - (order[a.measure] || Infinity) // to bottom 

 var array = [{ deviation: 57.41, provider: "This", measure: "median" }, { deviation: 49.02, provider: "All", measure: "median" }, { deviation: 199.67, provider: "This", measure: "third_quartile" }, { deviation: 152.31, provider: "All", measure: "third_quartile" }, { deviation: 41.48, provider: "This", measure: "first_quartile" }, { deviation: -1.07, provider: "All", measure: "first_quartile" }], order = { first_quartile: 1, median: 2, third_quartile: 3 }; array.sort(function (a, b) { return b.provider.localeCompare(a.provider) || order[a.measure] - order[b.measure]; }); console.log(array); 
 .as-console-wrapper { max-height: 100% !important; top: 0; } 

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