Hello,
I would like to be able to filter an existing Finder selection through AppleScript, using the name extension or a substring of the file name.
I can't make this simple code to work, which is quite frustrating:
tell application "Finder"
set lsFiles1 to selection
set lsFiles to (every item of lsFiles1 whose name ends with "dmg")
-- it could have been
-- set lsFiles to (every item of lsFiles1 whose name contains "abcde")
Hey rob, I would like to do it in AppleScript, as it is just a small part of the code.
Besides that, I know I could loop through the list and check every item name, but I'd like to understand what's wrong in the above syntax.
It's just a type issue – the selection object returned by Finder happens to be a list, rather than a reference to a collection.
i.e. you would have to work through the list items one by one, rather than applying some whose | where magic.
This kind of thing is possible, but it may be more involved than you need (a simple loop and test would be enough):
Expand disclosure triangle to view AppleScript source
tell application "Finder"
set xs to selection
script f
on |λ|(x)
if name of x ends with "dmg" then
{POSIX path of (x as alias)}
else
{}
end if
end |λ|
end script
my concatMap(f, xs)
-- or just a filter with a predicate
-- script p
-- on |λ|(x)
-- name of x ends with "dmg"
-- end |λ|
-- end script
--
-- my filter(p, xs)
end tell
-- concatMap :: (a -> [b]) -> [a] -> [b]
on concatMap(f, xs)
set lng to length of xs
set acc to {}
tell mReturn(f)
repeat with i from 1 to lng
set acc to acc & (|λ|(item i of xs, i, xs))
end repeat
end tell
acc
end concatMap
-- filter :: (a -> Bool) -> [a] -> [a]
on filter(p, xs)
tell mReturn(p)
set n to length of xs
set ys to {}
repeat with i from 1 to n
set v to item i of xs
if |λ|(v, i, xs) then set end of ys to v
end repeat
ys
end tell
end filter
-- mReturn :: First-class m => (a -> b) -> m (a -> b)
on mReturn(f)
-- 2nd class handler function lifted into 1st class script wrapper.
if script is class of f then
f
else
script
property |λ| : f
end script
end if
end mReturn
You indeed know AppleScript (and JavaScript), ComplexPoint. Thank you!!!
Checking your code, I ended up with a simpler solution, otherwise debugging at later times would have been impossible, given my limited understanding of AS.
Should it be of help, here it is:
set lsFiles to {}
tell application "Finder"
set lsFiles1 to selection as alias list
repeat with sFile in lsFiles1
if name extension of sFile is "dmg" then set lsFiles to lsFiles & sFile
end repeat
end tell