A way to reliably sort items in a Finder selection?

Hello, I have a question if anyone could help me figure it out. I’m I’ve basically got some files in Finder that are selected, and the files are set up in alphabetical order. (They’re gifs that will be joined into a larger gif using FFMPEG so the order is important.) For some reason, Finder in Big Sur is being difficult to work with. I would hope that this code

tell application "Finder"
	set theSel to (get selection as alias list)
	set path1 to POSIX path of (item 1 of theSel as alias)
end tell

would give me the path to the first item my selection as sorted by alphabetical order in the filename…but bizarrely, it’s assuming the first file I clicked on when making my selection is “item 1,” the second item I clicked on is “item 2” and so on.

I can’t find any easy way to get the finder selection and sort it, or otherwise work with by filename order, modification order, or anything.

Can anyone offer suggestions?

Welcome. FYI, code is easier to read and copy if you surround it by lines consisting of three tick marks (```). I’ve edited your post accordingly.

Try this code:

tell application "Finder"
	set theSel to sort (get selection) by name
	set path1 to POSIX path of (item 1 of theSel as alias)
end tell
1 Like

Thank you very much! I will be careful to do that in the future. This works perfectly!

And I’m glad I (re) discovered Script Debugger. I had dabbled with it many years ago but recently purchased version 8.0.

Shane, thanks for sharing your code.

I know this was in direct response to the OP, but as I’m sure you know, the Finder is often (always?) slow. This script took 14.87 sec to process 476 items on my fast 2019 iMac.

Is there a better (ASObjC?) solution for sorting that would be much faster, even if you have to start with the Finder’s selection?

Thanks.

If you want to sort by some property of URLs, such as the name (or lastPathComponent) as here, it’s reasonably simple and should be a bit faster:

use scripting additions
use framework "Foundation"

tell application "Finder"
	set theSel to selection as alias list
end tell

set theArray to current application's NSArray's arrayWithArray:theSel
-- make a sort descriptor that describes the key to sort on
set theDescriptor to current application's NSSortDescriptor's sortDescriptorWithKey:"lastPathComponent" ascending:true selector:"localizedStandardCompare:" -- Finder-style sorting
-- sort the array
set theList to (theArray's sortedArrayUsingDescriptors:{theDescriptor}) as list

If you want to support by something that’s not a simple property, such as modification date, you need a repeat loop to get the date from each URL separately, so the gain might not be worth it.

Thanks, Shane. This is much faster: Sorts 566 Finder Items in 1.03 sec.
Too bad there is not a better way to sort on dates.

This script returns a list of file references. Can it be easily changed to return a list of POSIX paths?

I know how to convert the list after the fact, but was hoping it could be done faster/better using ASObjC.

Thanks to @ShaneStanley and his BridgePlus script library, and his many posts, I have been able to put together a handler that lets you sort a file list based on any property of the file. Specifically this test script sorts on file modification date.

Sorts 551 Finder Items by Mod Date in 2.35 sec.

Thanks again, Shane.

Disclaimer: This script uses the deprecated info for command, which I really like and continues to work. I’m sure there is a System Events command that would also work.

property ptyScriptName : "How To Sort Finder Selection Based on Date"
property ptyScriptVer : "1.0"
property ptyScriptDate : "2021-05-22"
property ptyScriptAuthor : "JMichaelTX"

(*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
PURPOSE:
  • How To Sort Finder Selection Based on Date -- Uses BridgePlus
  
RETURNS:  List of File POSIX Paths Sorted by Modification Date

REQUIRED:
  1.  macOS 10.11.6+
  2.  Mac Applications
        • Finder
  3. Script Libraries
        • BridgePlus by @ShaneStanley
      
TAGS:  @SW.Finder @Lang.AS @Lang.ASObjC @CAT.Files @CAT.Sort @type.Example @Auth.Shane
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*)
use AppleScript version "2.5"
use scripting additions
use framework "Foundation" -- Required for all ASObjC commands

use BPLib : script "BridgePlus" -- Required for sortMultiLists()

tell application "Finder"
  set fileList to selection as alias list
end tell

set dateList to {}
repeat with oFileAlias in fileList
  set oFile to info for oFileAlias
  set end of dateList to modification date of oFile --  (info for oFile)
  set contents of oFileAlias to POSIX path of oFileAlias
end repeat

--- SORT First on Mod Date (Desc), and then on File Path (Asc) ---
set {dateList, fileList} to my sortMultiLists({dateList, fileList}, {"DESC", "ASC"})

return fileList

--> Sorts 551 Finder Items by Mod Date in 2.35 sec

--~~~~~~~~~~~~~~~~~~~~~~~ END OF MAIN SCRIPT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
on sortMultiLists(pListOfLists, pSortDirList) -- @Lists @Sort @BridgePlus @ASObjC
  --–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
  (*  VER: 1.0    2020-11-23
    PURPOSE:  
    PARAMETERS:
      • pListOfLists    | list |  List that contains two or more lists to be sorted
                                                    • Lists will be sorted by each sub-list in the order entered.
      • pSortDirList        | list |    List of text items indicating the sort direction for each list
                                                    • Must be "ASC" (for ascending) or
                                                    • "DESC" (for descending)

    RETURNS:  List of Lists in Sorted Order

    AUTHOR:  JMichaelTX
  REQUIRES:
    use framework "Foundation"
    use BPLib : script "BridgePlus"
  
    REF:  BridgePlus 1.3.3 Script Library, Shane Stanley
            https://latenightsw.com/support/freeware/
  --–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
  *)
  local rowsList, listCount, sortByList, iL, oSort
  
  --- Setup the Sort ---
  set rowsList to BPLib's colsToRowsIn:pListOfLists
  
  set listCount to count of pListOfLists
  set sortByList to {}
  
  --- Sort Order by List as Passed in pListOfLists ---
  
  repeat with iL from 1 to listCount
    set end of sortByList to iL
  end repeat
  
  --- Convert Text Sort Direction to Boolean ---
  --   (true means ascending)
  
  repeat with oSort in pSortDirList
    set contents of oSort to ((oSort as text) starts with "ASC")
  end repeat
  
  --- Do the Sort
  set rowsList to BPLib's sublistsIn:rowsList sortedByIndexes:sortByList ascending:pSortDirList sortTypes:{}
  
  --- Get Sort Results ---
  set pListOfLists to BPLib's colsToRowsIn:rowsList
  
  return pListOfLists
end sortMultiLists
--~~~~~~~~~~~~~~~~~~~~ END of Handler ~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Sure:

set theList to ((theArray's sortedArrayUsingDescriptors:{theDescriptor})'s valueForKey:"path") as list

If you’re happy to use that, this should be a bit faster:

use scripting additions
use framework "Foundation"
use script "BridgePlus"

tell application "Finder"
	set theSel to selection as alias list
end tell

load framework
set theArray to current application's SMSForder's resourceValuesForKeys:{current application's NSURLContentModificationDateKey, current application's NSURLPathKey} forURLsOrFiles:theSel
-- make a sort descriptor that describes the key to sort on
set theDescriptor to current application's NSSortDescriptor's sortDescriptorWithKey:(current application's NSURLContentModificationDateKey) ascending:false
-- sort the array
set theList to ((theArray's sortedArrayUsingDescriptors:{theDescriptor})'s valueForKey:(current application's NSURLPathKey)) as list
1 Like

Wow! Thank you Shane!
:+1:

Always like faster, and, in this case, much, much shorter code.

RESULTS: Sorted 551 Finder Items by date in 0.65 sec.:exclamation: