7 Replies Latest reply on Feb 1, 2019 9:04 PM by Sanford Whiteman

    Custom object multi-level ordering/sorting

    Jonathan Yang

      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}
      
        • Re: Custom object multi-level ordering/sorting
          Sanford Whiteman
          $sorter.sort($List_cList,["availabilityUpdated:desc","Availability:desc"])
          
          1 of 1 people found this helpful
            • Re: Custom object multi-level ordering/sorting
              Jonathan Yang

              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!

                • Re: Custom object multi-level ordering/sorting
                  Sanford Whiteman

                  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.

                  1 of 1 people found this helpful
                    • Re: Custom object multi-level ordering/sorting
                      Jonathan Yang

                      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?

                        • Re: Custom object multi-level ordering/sorting
                          Sanford Whiteman

                          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):

                           

                           

                          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.

                          1 of 1 people found this helpful