SOLVED

Custom object multi-level ordering/sorting

Go to solution
Highlighted
Level 2

Custom object multi-level ordering/sorting

Hi everyone,

I'm trying to figure out how to sort custom objects on multiple levels and need some assistance. So I'd sort by date/time with most recent at the top and then sort by boolean field with "true" values at the top. The result would be the most recent record with "true" value at the top. The below is kind of what I'm trying to achieve but, of course, this gives me an error. Any help is appreciated!

#set( $codeByMostRecent = $sorter.sort($List_cList,"availabilityUpdated:desc") && $sorter.sort($List_cList,"Availability:desc") )

#set( $latest_code = $codeByMostRecent[0] )

## Output

${latest_code.code}

1 ACCEPTED SOLUTION

Accepted Solutions
Highlighted
Level 10 - Community Moderator

Re: Custom object multi-level ordering/sorting

$sorter.sort($List_cList,["availabilityUpdated:desc","Availability:desc"])

View solution in original post

7 REPLIES 7
Highlighted
Level 10 - Community Moderator

Re: Custom object multi-level ordering/sorting

$sorter.sort($List_cList,["availabilityUpdated:desc","Availability:desc"])

View solution in original post

Highlighted
Level 2

Re: Custom object multi-level ordering/sorting

Hey Sanford,

Thank you for that. Didn't realize the solution was so simple...


Given how simple this script is, is there a circumstance in which this script would fail to output? I have a couple of records that I'm using to test this and 3 of the 4 records work but the last one just outputs token instead of the resulting code.

Also how would I account for records with the same date/time stamp with the value "true". Would a foreach be the simplest solution? Thanks in advance!

Highlighted
Level 10 - Community Moderator

Re: Custom object multi-level ordering/sorting

Given how simple this script is, is there a circumstance in which this script would fail to output? I have a couple of records that I'm using to test this and 3 of the 4 records work but the last one just outputs token instead of the resulting code.

Yes, there is. If the sorter encounters different datatypes for the same property, including null values, when comparing, the sort will fail.

What's fascinating about this, and probably worth a short blog post, is that you will only have a problem when values must be compared to break ties. For any fixed set of values, the outcome is deterministic, of course. But you could have 2 lists that look similar-ish from a 1000ft view, and one would throw an error and the other wouldn't, simply because of how many comparisons were required and whether 2 incompatible datatypes needed to be compared.

Also how would I account for records with the same date/time stamp with the value "true". Would a foreach be the simplest solution? Thanks in advance!

Yes, if they're sorted #foreach and #break when you see the first false.

Highlighted
Level 2

Re: Custom object multi-level ordering/sorting

I see. So in order to work around that would a #set on the CO fields be enough?

#set( $List_cList.Availability = { "1" : true, "" : false } )

#if( !$List_cList.availabilityUpdated.isEmpty() )

#set( $List_cList.availabilityUpdated = "yyyy-MM-dd'T'HH:mm" )

#end

#set( $codeByMostRecent = $sorter.sort($List_cList,["availabilityUpdated:desc","Availability:desc"]) )

#set( $latest_code = $codeByMostRecent[0] )

#foreach( $List_cList.Availability in $List_cList )

#if( $List_cList.Availability == false )

#break

#end

$latest_code.code

#end

Something to this effect maybe?

Highlighted
Level 10 - Community Moderator

Re: Custom object multi-level ordering/sorting

No, that won't work: you're trying to set defaults, I guess, on the ArrayList? No such method exists. Also, empty and null aren't the same. An empty String and a non-empty String are still the same datatype, so comparing them isn't the problem.

I'm glad to see a real-world person encountering this (other than me) because this is one of my blog drafts right now (admittedly, one of about 20 that are works in progress):

pastedImage_3.png

However, until that blog post is published you won't know how to do it the totally right way, which is to use what's called a Null-Safe Comparator.

What you can do in the interim, and I hate to recommend it but have no choice right now, is loop over the list once and transform the null values into a representative value with the expected type:

#foreach( $item in $List_cList )

#if( !$item.Availability.class )

#set( $item.Availability = true )

#end

#if( !$item.availabilityUpdated.class )

#set( $item.availabilityUpdated = "0000-00-00" )

#end

#end

This works by checking to see if the values have a class. nulls won't have a class, so you can then set them to what you want the default to be. Then sort after that.

Highlighted
Level 2

Re: Custom object multi-level ordering/sorting

Thank you Sanford!

One last question, I'm having a bit of an issue with the last bit. I feel like I'm missing something obvious but can't figure it out. Any pointers?

#foreach( $codeByMostRecent.Availability in $List_cList )

#if( $List_cList.Availability == '' )

#break

#end

$latest_code.code

#end

Highlighted
Level 10 - Community Moderator

Re: Custom object multi-level ordering/sorting

No idea what you're trying to do here, but the syntax is not valid whatever it is. What's "the last bit"?

If you want to walk the (already sorted and de-null-ed) list until you see a false, do:

#foreach( $item in $sortedList )

#if( $item.Availability.equals(false)

#break

#else

${item} has Availability == true and is (or is tied for) the most recent item x`in the list.

#end