1

I have an array with roughly 50 JS objects inside, each object in the array has a name, catname, dish_sort_id and sort_id

currently i am trying to sort it so that in the array it goes group objects via catname and if dish_sort_id < then dish_sort_id of next object. Below is the code i am using to sort the array

despite using this code some items are appearing in the wrong order, but they are being sorted

A.sort(function(a,b){
        if(a.catname == b.catname && a.dish_sort_id > b.dish_sort_id){
            return -1;
        } else if(a.catname == b.catname && a.dish_sort_id < b.dish_sort_id){
            return 1;
        } else if(a.catname == b.catname && a.dish_sort_id == b.dish_sort_id){
            return 0;
        }
    });
6
  • 5
    Okay. And you're here because... ? Btw, if a and b guaranteed to have equal catname for all entries - why do you still compare them? And if they are not - where is the corresponding return for such a case? Commented Apr 24, 2015 at 10:59
  • Edit the question and add the expected and actual output. That will make some things clear. Commented Apr 24, 2015 at 11:02
  • No they are different basically what is happening is to sort them by the catname and in order of dish_sort_id e.g. food 1 food 2 food 3 then drink 1 drink 2 and so on Commented Apr 24, 2015 at 11:02
  • If they are different - why don't you compare them? Do you realize you return undefined in case if they are different? Are you aware that Array.prototype.sort() callback MUST return one of {-1, 0, 1}? Commented Apr 24, 2015 at 11:03
  • 1
    Well, what do you think happens if the a.catname == b.catname comparison is not true? Commented Apr 24, 2015 at 11:05

1 Answer 1

4

Your callback is breaking the contract: It doesn't return anything if catname is the same on the two objects you're comparing. And separate from breaking the contract, that's also why it's not working correctly.

This is a standard case of a multi-key sort, which you do by the first key, then the second key, etc. For instance, this sorts by catname (ascending) and, within catnames, by dish_sort_id (descending, as that seemed to be what your code did):

A.sort(function(a,b){
    var rv = a.catname.localeCompare(b.catname);
    if (rv == 0) {
        // Same name, use the dish_sort_id
        rv = b.dish_sort_id - a.dish_sort_id;
    }
    return rv;
});

Live example:

var name1 = randomName();
var name2 = randomName();
var A = [
    { catname: name2, dish_sort_id: randomNumber() },
    { catname: name1, dish_sort_id: randomNumber() },
    { catname: name1, dish_sort_id: randomNumber() },
    { catname: name2, dish_sort_id: randomNumber() },
    { catname: name2, dish_sort_id: randomNumber() },
    { catname: name1, dish_sort_id: randomNumber() }
];
show("Before", A);
A.sort(function(a,b){
    var rv = a.catname.localeCompare(b.catname);
    if (rv == 0) {
        // Same name, use the dish_sort_id
        rv = b.dish_sort_id - a.dish_sort_id;
    }
    return rv;
});
snippet.log("----");
show("After", A);

function show(label, a) {
  snippet.log(label + ":");
  A.forEach(function(entry) {
      snippet.log(entry.catname + " - " + entry.dish_sort_id);
  });
}

function randomName() {
    var rv = "";
    while (rv.length < 5) {
        rv += String.fromCharCode(65 + Math.floor(Math.random() * 26));
    }
    return rv;
}
function randomNumber() {
    return Math.floor(Math.random() * 10);
}
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.