3

I have a list with both numbers and strings in there.

Each element of the list looks something like:

{
  'name': 'Bob',
  'number': 234234
}

But, either name or number may be missing.

In my sortBy I did something like this:

_.sortBy(list, function(element) {
  if (element.name) {
    return element.name;
  }
  else {
    return element.number;
  }
});

This sorts the elements with numbers in front of the elements without it. How do I get lodash to deprioritize numbers?

3
  • Would you be willing to use a native JavaScript solution, or do you want to stick with lodash?
    – user3886234
    Commented Feb 12, 2015 at 2:27
  • I figured out a native JS solution using the .sort() function, but it ended up being much much longer than a sortBy solution would have been. I'm ok keeping it this way for now, but if someone has a better idea I'd appreciate that too. Commented Feb 12, 2015 at 2:37
  • 1
    What's your intended output here? All entires with names, sorted by name, followed by all entries with number, sorted by number?
    – Retsam
    Commented Feb 18, 2015 at 18:04

3 Answers 3

1

I guess what you mean is simply that _.sortBy ranks in ascending order?

sortBy_.sortBy(list, iteratee, [context]) Returns a (stably) sorted copy of list, ranked in ascending order by the results of running each value through iteratee. iteratee may also be the string name of the property to sort by (eg. length).

http://underscorejs.org/#sortBy

Therefore, as you are prioritizing element.name, it appears last on the sort.

You can simply reverse the resulting array

results = results.reverse();

Or, change the order of your if/else statement.

1

_.sortBy is using the return value to create an object with a criteria property. That criteria property is the value to compare with the array.sort function and an ad hoc, not configurable comparer function.

I guess you can hack this, returning a value like:

    _.sortBy(list, function(element) {
      if (element.name) {
        return "@" + element.name;
      }
      else {
        return element.number;
      }
    };
1

It sounds like it might be easier to split the list, sort the parts and put it back together, i.e.:

 _(data) //begin chain
    .filter("name") //the entries with names
    .sortBy("name") //sorted by name
    .concat(_.sortBy(_.reject(data, "name"), "number")) //followed by the entries without name, sorted by number
    .value(); //end chain

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.