Re: Position of an element in a list
Re: Position of an element in a list
- Subject: Re: Position of an element in a list
- From: jif <email@hidden>
- Date: Tue, 1 Aug 2017 16:04:11 +0100
Or, bubbling the boolean and possible integer values up through nested function
calls, we can generalise a search through a flat list to a 'chapter and verse
or not found' (possible compound index) function over a search string and list
of lists, nested to an arbitrary depth, deriving a result like:
"Para 2, Line 1, Word 10"
from something along the lines of:
property lstParas : {{{"Donec", "ut", "dui", "nisi", "Mauris", "fringilla",
"sem", "nec", "consectetur"}, {"imperdiet", "erat", "mauris", "bibendum",
"purus", "et", "varius", "nulla", "nisi", "non", "quam"}, {"Pellentesque",
"nulla", "eros", "dignissim", "sit", "amet", "justo", "sit", "amet",
"bibendum", "auctor"}, {"nibh", "Aenean", "magna", "sem", "tempus", "quis",
"vestibulum", "ut", "tempor", "sed", "enim", "Cras"}, {"elementum", "eleifend",
"ante", "at", "interdum", "nisi", "vehicula", "id"}}, {{"Nulla", "laoreet",
"mauris", "eu", "placerat", "bibendum", "Aenean", "ligula", "erat", "kappa",
"aliquet", "at"}, {"blandit", "eu", "ornare", "ultricies", "purus", "Duis",
"et", "risus", "augue", "Morbi", "tincidunt", "ex"}, {"at", "sagittis",
"semper", "Phasellus", "in", "condimentum", "sapien", "Fusce", "quis",
"tellus", "ornare"}, {"fringilla", "elit", "at", "fringilla", "diam", "Ut",
"auctor", "tempor", "laoreet", "Quisque", "vitae"}, {"nunc", "in", "ligula",
"vestibulum", "finibus", "vel", "quis", "neque", "Pellentesque", "dapibus",
"nisl"}, {"nec", "magna", "semper", "ac", "ultrices", "felis", "elementum"}},
{{"Vestibulum", "posuere", "lectus", "ex", "eu", "scelerisque", "nisi",
"tristique", "at", "Quisque", "nec"}, {"tincidunt", "tortor", "Duis", "a",
"ligula", "in", "justo", "viverra", "convallis", "Nam", "malesuada"},
{"tristique", "est", "Donec", "lobortis", "felis", "sed", "eros", "egestas",
"a", "venenatis", "massa"}, {"pharetra", "Integer", "sed", "ullamcorper",
"nibh"}}}
on run
set strNeedle to "kappa"
set maybe to subIndex(strNeedle, lstParas)
if nothing of maybe then
strNeedle & " not found"
else
script labelled
on |λ|(k, v)
k & " " & v
end |λ|
end script
intercalate(", ", zipWith(labelled, {"Para", "Line", "Word"},
just of maybe))
end if
--> "Para 2, Line 1, Word 10"
end run
-- GENERIC FUNCTIONS
---------------------------------------------------------------------------
-- elemIndex :: a -> [a] -> Maybe Int
on elemIndex(x, xs)
set lng to length of xs
repeat with i from 1 to lng
if x = (item i of xs) then return {just:i, nothing:false}
end repeat
return {nothing:true}
end elemIndex
-- foldl :: (a -> b -> a) -> a -> [b] -> a
on foldl(f, startValue, xs)
tell mReturn(f)
set v to startValue
set lng to length of xs
repeat with i from 1 to lng
set v to |λ|(v, item i of xs, i, xs)
end repeat
return v
end tell
end foldl
-- intercalate :: Text -> [Text] -> Text
on intercalate(strText, lstText)
set {dlm, my text item delimiters} to {my text item delimiters, strText}
set strJoined to lstText as text
set my text item delimiters to dlm
return strJoined
end intercalate
-- min :: Ord a => a -> a -> a
on min(x, y)
if y < x then
y
else
x
end if
end min
-- Lift 2nd class handler function into 1st class script wrapper
-- mReturn :: Handler -> Script
on mReturn(f)
if class of f is script then
f
else
script
property |λ| : f
end script
end if
end mReturn
-- subIndex :: a -> [b] -> Maybe [Int]
on subIndex(needle, nest)
script subSearch
on |λ|(a, xs, i)
if nothing of a then
if length of xs < 1 then
a -- Nothing to see here
else if class of item 1 of xs is list then
set mb to subIndex(needle, xs) -- still
nested
else
set mb to elemIndex(needle, xs) --
bottom level
end if
if nothing of mb then
mb -- {nothing: true} bubbling up
else
{just:{i} & just of mb, nothing:false}
end if
else
a -- Accumulator already contains result
end if
end |λ|
end script
foldl(subSearch, {nothing:true}, nest)
end subIndex
-- unwords :: [String] -> String
on unwords(xs)
intercalate(space, xs)
end unwords
-- zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
on zipWith(f, xs, ys)
set lng to min(length of xs, length of ys)
set lst to {}
tell mReturn(f)
repeat with i from 1 to lng
set end of lst to |λ|(item i of xs, item i of ys)
end repeat
return lst
end tell
end zipWith
_______________________________________________
Do not post admin requests to the list. They will be ignored.
AppleScript-Users mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
Archives: http://lists.apple.com/archives/applescript-users
This email sent to email@hidden