4

I have the following structure:

var participant0 = {
    name : "",
    nickname : "",
    number "99999"
} ;

var participant1 = {
    name : "bbb",
    nickname : "",
} ;

var participant2 = {
    name : "",
    nickname : "aaa"
} ;

var participant3 = {
    name : "ccc",
    nickname : ""
} ;

And i have an array which contain instances of structure :

var array = [participant0, participant3, participant1, participant2];

I would like to sort this array by alphabetical letter. First on name, second on nickname. If these two keys doesn't exist, i would like to check the number key and put this element at the end of the sorting list.

Expected result :

var array = [participant2, participant1, participant3, participant0];

(To have sorted object by "aaa", "bbb", "ccc", "9999")

The following code working fine to sort by name or nickname but i don't know how put the item at the end of the sorting list if there is the number key :

fav_list.sort(function(x, y) {
              return (x.participant.name || x.participant.nickname).localeCompare(y.participant.name || y.participant.nickname);
            });
3
  • Why participant2 in the result should be before participant1? Does really nickname="aaa" < nickname=""? Commented Apr 24, 2015 at 9:55
  • 1
    When comparing "2" and "10" which one comes first? Commented Apr 24, 2015 at 9:58
  • 1
    @hindmost nickname="aaa" < name="bbb". Are these sort rules strange? Yes, they are, but this is what OP wants. Commented Apr 24, 2015 at 10:00

5 Answers 5

2

I think this should do it, see the comments in the code:

fav_list.sort(function(x, y) {
    var xvalue = x.participant.name || x.participant.nickname;
    var yvalue = y.participant.name || y.participant.nickname;
    // By name if both have names
    if (xvalue && yvalue) {
        return xvalue.localeCompare(yvalue);
    }
    // Names always come before numbers
    if (xvalue) {
        return -1;
    }
    if (yvalue) {
        return 1
    }
    // Otherwise compare numbers
    return (x.participant.number || 0) - (y.participant.number || 0);
});

You may want to play with the default numbers (the zeroes) in the last line.

Note that the array you've shown doesn't quite match up with that code, because the array uses the participants directly, but the code is expecting the participants to be on a participant property of an object.

Live example with slightly-adjusted array and a handy way to tell what order we ended up with:

var participant0 = {
  name: "",
  nickname: "",
  number: "99999",
  debug: 0
};

var participant1 = {
  name: "bbb",
  nickname: "",
  debug: 1
};

var participant2 = {
  name: "",
  nickname: "aaa",
  debug: 2
};

var participant3 = {
  name: "ccc",
  nickname: "",
  debug: 3
};

var array = [
  {
    participant: participant0
  },
  {
    participant: participant3
  },
  {
    participant: participant1
  },
  {
    participant: participant2
  }
];

array.sort(function(x, y) {
  var xvalue = x.participant.name || x.participant.nickname;
  var yvalue = y.participant.name || y.participant.nickname;
  // By name if both have names
  if (xvalue && yvalue) {
    return xvalue.localeCompare(yvalue);
  }
  // Names always come before numbers
  if (xvalue) {
    return -1;
  }
  if (yvalue) {
    return 1
  }
  // Otherwise compare numbers
  return (x.participant.number || 0) - (y.participant.number || 0);
});
array.forEach(function(entry) {
  snippet.log(entry.participant.debug);
});
<!-- 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.

2 Comments

Sometimes, this code returns : Uncaught TypeError: xvalue.localCompare is not a function
@wawanopoulos: It should be localeCompare, not localCompare. The snippet was right but the code example at the top was wrong, sorry about that -- it's fixed now.
1

Don't do everything at once.

fav_list.sort(function(x,y) {
    var xname = x.name || x.nickname || "\uffff"+x.number;
    var yname = y.name || y.nickname || "\uffff"+y.number;
    return xname.localeCompare(yname);
});

The "\uffff" is to force numbers to go at the end ;)

1 Comment

I'd be leery of localeCompare and \uffff working globally. But this is still wonderfully creative and succinct. :-) Sorts the numbers alphabetically at the end (so 2 before 10), but easily adjusted to handle that if it's important.
0

The code can be written as :

\uffff is directly interpreted as the desired string, and the whole sequence is realized as a single character

var participant0 = {
    name : "",
    nickname : "",
    number: "99999"
} ;

var participant1 = {
    name : "bbb",
    nickname : ""
} ;

var participant2 = {
    name : "",
    nickname : "aaa"
} ;

var participant3 = {
    name : "ccc",
    nickname : ""
} ;
var array = [participant0, participant3, participant1, participant2];
console.log(array.sort(function(x,y) {
    var val1 = x.name || x.nickname || "\uffff"+x.number;
    var val2 = y.name || y.nickname || "\uffff"+y.number;
    return xname.localeCompare(val2);
}))
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

Comments

0
function sortObject(object) { // sort Object by key
    var sorted = {},
        key, a = [];
    for (key in object) {
        if (object.hasOwnProperty(key)) {
            a.push(key);
        }
    }
    a.sort();
    for (key = 0; key < a.length; key++) {
        sorted[a[key]] = object[a[key]];
    }
    return sorted;
}

function sortArray(arr){//sort array of objects
    var array=[];
    for(var i=0;i<arr.length;i++){
        array.push(sortObject(arr[i]));
    }
    return array;
}

var arr=[{a:'1',c:'2',b:'3'},{c:'1',b:'2',a:'3'}];
console.log('===>',sortArray(arr));

Comments

-1

You colud try work around.

  var numbers = [];    
fav_list.sort(function(x, y) {  
             if(!isNaN(x)){
              numbers.push(x);
             continue;
             }
                  return (x.participant.name || x.participant.nickname).localeCompare(y.participant.name || y.participant.nickname);
                });
    fav_list.push(numbers);

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.