0

I have seen questions and answers how to sort array by one value (text or number) and by two numbers (years and count of something).

How can I sort by one string in Ascending order and another string in special order?

Here is one object from array

var stop = {
    type: "S", // values can be S, C or H. Should ordered S, C and then H.
    street: "SW Dummy St." // Should be sorted in ascending order
}

And expected end result should look like this

var data = [
    { type: 'S', year: 'SW Karp' },
    { type: 'S', year: 'SW Walker' },
    { type: 'C', year: 'SW Greth' },
    { type: 'C', year: 'SW Main' }
    { type: 'H', year: 'SW Dummy' }
];
2
  • 1
    possible duplicate of How to sort an array of objects by multiple fields? Commented Mar 8, 2012 at 13:28
  • Just to make sure: You can use the function in my answer there and use a special primer for the type, returning e.g. a number for each letter, such as 0 for S, 1 for C and 2 for H: data.sort(sort_by({name: 'type', primer: function(x) { return ({'S':0, 'C':1, 'H':2})[x];}}, 'street')); Commented Mar 8, 2012 at 13:40

3 Answers 3

5

The Array.sort() method accepts a sort function, which allows you to implement the sorting yourself.

data.sort(function (a, b) {
    // Specify the priorities of the types here. Because they're all one character
    // in length, we can do simply as a string. If you start having more advanced
    // types (multiple chars etc), you'll need to change this to an array.
    var order = 'SCH';
    var typeA = order.indexOf(a.type);
    var typeB = order.indexOf(b.type);

    // We only need to look at the year if the type is the same
    if (typeA == typeB) {
        if (a.year < b.year) {
            return -1;
        } else if (a.year == b.year) {
            return 0;
        } else {
            return 1;
        }

    // Otherwise we inspect by type
    } else {
        return typeA - typeB;
    }
});

Array.sort() expects 0 to be returned if a == b, < 0 if a < b and > 0 if a > b.

You can see this working here; http://jsfiddle.net/32zPu/

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

3 Comments

This works. I could think of a way to sort by type in special order. Thank you
S,C and H are not in alphabetical order :P
@missingno: From the OP's code: Should ordered S, C and then H..
2

I've upvoted Matt's answer, but wanted to add a slightly different approach for getting the sort order from the type which can work for values beyond just single characters and a bit shorter way to compare the year values:

data.sort(function(a, b) {
    var order = {"S": 1,"C": 2,"H": 3}, typeA, typeB;
    if (a.type != b.type) {
        typeA = order[a.type] || -1;
        typeB = order[b.type] || -1;
        return(typeA - typeB);
    } else {
        return(a.year.localeCompare(b.year));
    }
});

Working demo: http://jsfiddle.net/jfriend00/X3rSj/

1 Comment

+1 for localeCompare... I've never come across that before!
0

You can pass a custom function to the array sort method that lets you define how the items are sorted. Something like this should work (your unsorted data would be in the 'data' var):

function sortFunc (item1, item2) {
  var sortOrder = 'SCH';
  if (item1.type != item2.type)
  {
    return sortOrder.indexOf(item1.type) - sortOrder.indexOf(item2.type);
  }
  else
  {
    return item1.year.localeCompare(item2.year);
  }
}

var sortedData = data.sort(sortFunc);

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.