Working with Lists: Retrieving List Items by their Class

Many users are unaware that AppleScript is very powerful at retrieving list items by item class.

I tested here for myself and for the general good. The results are impressive, and I think it will be useful to other users to improve the efficiency of scripts:


use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions

set aList to {"1", "a", pi, false, {"nestedList"}, "g", 2, 7, 9, 3.14, path to desktop folder, (path to home folder) as text as «class furl», {theKey:"theValue"}, current date, (path to system folder) as text as POSIX file}


-- getting numbers
numbers of aList --> {3.14159265359, 2, 7, 9, 3.14}
integers of aList --> {2,7,9}
reals of aList --> {3.14159265359, 3.14}
-- following info added by @Nigel Garvey: retrieve by class & by index
numbers 1 thru 3 of aList --> {3.14159265359, 2, 7}


-- getting strings
text of aList --> {"1", "a", "g"}
every string of aList --> {"1", "a", "g"}

-- getting booleans
booleans of aList --> {false}

-- getting dates
dates of aList --> {date "Saturday, 6 August 2022 - 8:21:59 PM"}

-- getting records and nested lists
records of aList --> {{theKey:"theValue"}}
lists of aList --> {{"nestedList"}}

-- getting file system references
aliases of aList --> {alias "Apple HD:Users:123:Desktop:"}
every «class furl» of aList --> {file "Apple HD:Users:123:", file ":Apple HD/System/"}

Perhaps there are other classes with which you can retrieve list items. If you notice something I missed, please add the example(s) to this thread.


set theListItems to items of aList


tell application "Finder"
	set theFinderItems to items of aList
end tell

You can also use index and range specifiers to get specific instances of a class:


set aList to {"1", "a", pi, false, {"nestedList"}, "g", 2, 7, 9, 3.14, path to desktop folder, (path to home folder) as text as «class furl», {theKey:"theValue"}, current date, (path to system folder) as text as POSIX file}

numbers 1 thru 3 of aList --> {3.14159265359, 2, 7}

Informative.

This won’t work:


tell application "Finder" to set aList to every folder of desktop
set aList to {"ADDING"} & aList
tell application "Finder" to every item of aList

Whoops, it doesn’t work. (I was looking at a different result)

but these work:



count numbers of aList
count text of aList 

One could for instance use the idea in a fast routine to randomise a list:

on randomise(theList) -- Randomise a list in place.
	-- copy theList to theList -- Uncomment to randomise a copy instead.
	script o
		property lst : theList
		property indices : {}
	end script
	
	set listLen to (count theList)
	-- Build an ordered list of indices to the positions in the list.
	repeat with i from 1 to listLen
		set end of o's indices to i
	end repeat
	
	repeat with j from listLen to 1 by -1 --1 to listLen
		-- Swap item j of the list with the item indexed by one of the indices
		-- still in the index list — including with itself, if that's how it pans out!
		set i to some integer of o's indices -- NB. 'some integer'
		tell o's lst's item j
			set o's lst's item j to o's lst's item i
			set o's lst's item i to it
		end tell
		-- Replace the index used this time with a non-integer.
		set o's indices's item i to missing value
	end repeat
	
	-- return theList -- Uncomment if randomising a copy or simply if preferred.
end randomise

set aList to {"1", "a", pi, false, {"nestedList"}, "g", 2, 7, 9, 3.14, path to desktop folder, (path to home folder) as text as «class furl», {theKey:"theValue"}, current date, (path to system folder) as text as POSIX file}
randomise(aList)
return aList

Cool. :slight_smile: