orderBy string filter to favor whitespace as an 'earlier' sorted word than if additional digit

61 views
Skip to first unread message

Chris Dieringer

unread,
Jul 21, 2014, 8:06:57 PM7/21/14
to ang...@googlegroups.com
Hi all:

If I have the following strings:

  1. Week 1
  2. Week 10
  3. Week 2
They will be sorted in that order using a traditional orderBy:thatPropertyName.  This is probably less of an angular question and more of a js question, but thought I'd ask regardless.  If I want the above to be sorted properly, is there a quick trick?


Much appreciated!

-Chris

Tobiah

unread,
Jul 22, 2014, 12:40:40 PM7/22/14
to ang...@googlegroups.com, christophe...@gmail.com
On 07/21/2014 05:06 PM, Chris Dieringer wrote:
> Hi all:
>
> If I have the following strings:
>
> 1. Week 1 2. Week 10 3. Week 2
>
> They will be sorted in that order using a traditional
> orderBy:thatPropertyName. This is probably less of an angular
> question and more of a js question, but thought I'd ask regardless.
> If I want the above to be sorted properly, is there a quick trick?

One way that you can do this is to pass a function to sort()
to do the sorting that way you want to:



<script>
var strings = ["Week 1", "Week 10", "Week 2"];

document.write(strings.sort(sort_num));

function sort_num(left, right){
return parseInt(left.split(' ')[1]) > parseInt(right.split(' ')[1]);
}
</script>




This puts out:

Week 1, Week 2, Week 10


If the strings are less predictable, you
could use regular expressions to remove
non-numeric characters before the parseInt().

Tobiah

Chris Dieringer

unread,
Jul 22, 2014, 2:49:45 PM7/22/14
to ang...@googlegroups.com
Cool, thanks Tobias.  I ended up writing a sort comparator function that is flexible to handle many cases where numbers will be in unpredictable places in the string.  Some examples shared below.  Trouble is, this sort function is intended for use with native js String.sort().  How would I wire up my new sort() mechanism with a repeat directive who is repeating over an a string property of objects?

My super sort function and test data!


  • Week 30
  • Week 5
  • Week 3
==>
  • Week 3
  • Week 5
  • Week 30
AND

  • 27str
  • 2str
  • 22str
==>
  • 2str
  • 22str
  • 27str

Tobiah

unread,
Jul 22, 2014, 3:32:48 PM7/22/14
to ang...@googlegroups.com, christophe...@gmail.com
Can't you just do:

<thing ng-repeat='thing in my_sort_routine(data_i_want)'>

Then you can sort your array and return it.

I'm not so hot at angular yet so I'm not sure.

Tobih

On 07/22/2014 11:49 AM, Chris Dieringer wrote:
> Cool, thanks Tobias. I ended up writing a sort comparator function that is flexible to handle many cases where numbers will be in unpredictable places in the string. Some examples shared below. *Trouble is*, this sort function is intended for use with native js String.sort(). How would I wire up my new sort() mechanism with a repeat directive who is repeating over an a string property of objects?
>
> My super sort function and test data!
> http://jsfiddle.net/cdaringe/LfHPT/
>
>
> * Week 30
> * Week 5
> * Week 3
>
> ==>
>
> * Week 3
> * Week 5
> * Week 30
>
> AND
>
> * 27str
> * 2str
> * 22str
>
> ==>
>
> * 2str
> * 22str
> * 27str
>
> --
> You received this message because you are subscribed to the Google Groups "AngularJS" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to angular+u...@googlegroups.com <mailto:angular+u...@googlegroups.com>.
> To post to this group, send email to ang...@googlegroups.com <mailto:ang...@googlegroups.com>.
> Visit this group at http://groups.google.com/group/angular.
> For more options, visit https://groups.google.com/d/optout.

Chris Dieringer

unread,
Jul 22, 2014, 4:43:35 PM7/22/14
to ang...@googlegroups.com, christophe...@gmail.com
With the new direction of using a custom sort comparator, the thread description should really read something more like:

"howto use orderBy custom sort when iterating over objects"

Tobias, thanks for the feedback.  Indeed I cannot quite do as you suggest, as I'm iterating over a raw object{}, not an Array(), thus I can't sort the obj in advance.  I've also always been under the impression that we should never really rely on sorted objects, as they are unsorted by definition in the spec, and browsers are not required to maintain their order.

Rather, I need to sort the ?array generated by ng-repeat?, somehow, assuming ng-repeat generates one :) .

Also, i updated my sorter code:  http://jsfiddle.net/cdaringe/LfHPT/6/

Any other ideas (, all)?  I'm sure it's fairly simple I just need to find the correct wires to plug in!

Chris Dieringer

unread,
Jul 22, 2014, 4:44:11 PM7/22/14
to ang...@googlegroups.com, christophe...@gmail.com
Apologies, Tobiah ***

Tobiah

unread,
Jul 22, 2014, 5:43:37 PM7/22/14
to ang...@googlegroups.com, christophe...@gmail.com

> Tobias, thanks for the feedback. Indeed I cannot quite do as you
> suggest, as I'm iterating over a raw object{}, not an Array(), thus I
> can't sort the obj in advance.

You can represent order and key/val relationship with a
more complex data structure. I do this all the time.
Stuff each key/val pair of your object into an array,
then use your custom sort function to compare the values of
each object in the array (http://tobiah.org/foo.html).

<script>

var ob = {
'dog': 'canine',
'cow': 'bovine',
'horse': 'equestrian',
'cat': 'feline'
}

console.log(ob_sorter(ob));

function ob_sorter(ob){

var holder = [];

for(var x in ob){
holder.push({key: x, val: ob[x]});
}

holder.sort(val_sort);

return holder
}

function val_sort(left, right){
return left.val > right.val
}
</script>


Then you can utilize the sorted pairs in a slightly different way:

<span ng-repeat='pair in my_ob'>

{{pair.key}}{{pair.val}} or whatever you wanted to do with them.

</span>

If you want to sort by keys, just use left.key > right.key in the val_sort().

Tobiah










Chris Dieringer

unread,
Jul 23, 2014, 10:02:58 PM7/23/14
to ang...@googlegroups.com
Hi Tobiah:

I realize that I may have mislead.  Let me be more explicit about my issue.  

I have an Array, $scope.array.  Within the array, there are objs w/ props.  I.e., $scope.array[arbitrary-n] = {prop1: '1', prop2: '2'..., propN-1:'n-1'};

<div ng-repeat="obj as obj.prop1 for obj in array | orderBy:'+prop2' track by obj.propN-1>
  <span ng-bind="...(to some obj.prop)..." />
  <p>Blah blah blah {{obj.someOtherProp}}</p>
</div>

I use other properties of the obj during the repeat.  Thus, the question is, how does one continue to iterate over the Array of objects, but sort them using a custom sorter based on a sub-object property.  Sure, I could manipulate my actual data on the scope, but I have a hunch I don't need to do that.  Not that it would be a huge deal, but it doesn't feel too angular-esque!  :)  Perhaps I'm just a dreamer...

Also, looks like your server is down :(

Chris Dieringer

unread,
Jul 23, 2014, 10:05:52 PM7/23/14
to ang...@googlegroups.com
Wow, was not thinking. Nm.  Thanks!
Reply all
Reply to author
Forward
0 new messages