You are not logged in.
I wrote the following script which gets and sorts all files and folders in a folder in the exact order they are shown in a Finder window. The Finder window is set to sort by name in ascending order with folders displayed first and hidden files not shown. The following works but I wondered if there might be a simpler and faster ASObjC approach. I wrote this primarily to refine my ASObjC skills. Thanks.
Applescript:
use framework "Foundation"
use scripting additions
set theFolder to POSIX path of (choose folder)
getFinderList(theFolder)
on getFinderList(theFolder)
set theFolder to current application's |NSURL|'s fileURLWithPath:theFolder
set fileManager to current application's NSFileManager's defaultManager()
set theOptions to (current application's NSDirectoryEnumerationSkipsPackageDescendants as integer) + (current application's NSDirectoryEnumerationSkipsHiddenFiles as integer)
set enumKeys to {current application's NSURLIsDirectoryKey, current application's NSURLIsPackageKey}
set theFiles to fileManager's contentsOfDirectoryAtURL:theFolder includingPropertiesForKeys:enumKeys options:theOptions |error|:(missing value)
set theDescriptor to current application's NSSortDescriptor's sortDescriptorWithKey:"lastPathComponent" ascending:true selector:"localizedStandardCompare:"
set sortedFiles to (theFiles's sortedArrayUsingDescriptors:{theDescriptor})
set theFolders to current application's NSMutableArray's new()
set theFiles to current application's NSMutableArray's new()
repeat with anItem in sortedFiles
set {theResult, isDirectory} to (anItem's getResourceValue:(reference) forKey:(current application's NSURLIsDirectoryKey) |error|:(missing value))
if isDirectory as boolean then
set {theResult, isPackage} to (anItem's getResourceValue:(reference) forKey:(current application's NSURLIsPackageKey) |error|:(missing value))
if isPackage as boolean then
(theFiles's addObject:anItem)
else
(theFolders's addObject:anItem)
end if
else
(theFiles's addObject:anItem)
end if
end repeat
set finderItemList to theFolders's arrayByAddingObjectsFromArray:theFiles
return finderItemList as list
end getFinderList
2018 Mac mini - macOS Monterey - Script Debugger 8
Offline
Hi peavine.
If you know you have significantly fewer folders than files in the folder, or vice versa, a v-e-r-y slightly more efficient approach would be only to build an array of the fewer items and then "subtract" it from the full one. This may even be effective with a more even mix.
Applescript:
use framework "Foundation"
use scripting additions
set theFolder to POSIX path of (choose folder)
getFinderList(theFolder)
on getFinderList(theFolder)
set theFolder to current application's |NSURL|'s fileURLWithPath:theFolder
set fileManager to current application's NSFileManager's defaultManager()
set theOptions to (current application's NSDirectoryEnumerationSkipsPackageDescendants as integer) + (current application's NSDirectoryEnumerationSkipsHiddenFiles as integer)
set enumKeys to {current application's NSURLIsDirectoryKey, current application's NSURLIsPackageKey}
set theFiles to (fileManager's contentsOfDirectoryAtURL:theFolder includingPropertiesForKeys:enumKeys options:theOptions |error|:(missing value))
set theFiles to theFiles's mutableCopy()
set theDescriptor to current application's NSSortDescriptor's sortDescriptorWithKey:"lastPathComponent" ascending:true selector:"localizedStandardCompare:"
theFiles's sortUsingDescriptors:{theDescriptor}
set arrangedItems to current application's NSMutableArray's new() -- Formerly theFolders.
repeat with anItem in theFiles
set {theResult, isDirectory} to (anItem's getResourceValue:(reference) forKey:(current application's NSURLIsDirectoryKey) |error|:(missing value))
if isDirectory as boolean then
set {theResult, isPackage} to (anItem's getResourceValue:(reference) forKey:(current application's NSURLIsPackageKey) |error|:(missing value))
if not (isPackage as boolean) then (arrangedItems's addObject:anItem)
end if
end repeat
theFiles's removeObjectsInArray:arrangedItems
arrangedItems's addObjectsFromArray:theFiles
return arrangedItems as list
end getFinderList
NG
Offline
Thanks Nigel. Your suggestion works great but I had to put it to the test
TEST FOLDER CONTAINS - PEAVINE'S SCRIPT - NIGEL'S SCRIPT
8 folders 8 files - 41 - 37 (all times are milliseconds)
4 folders 16 files - 38 - 32
2 folders 57 files - 83 - 61
To set a baseline, I tested a Finder script which returns the same results (except as aliases) on the third test folder above and the timing result was 288 milliseconds.
Last edited by peavine (2021-08-10 06:58:43 pm)
2018 Mac mini - macOS Monterey - Script Debugger 8
Offline