Unique characters: Difference between revisions

Content added Content deleted
Line 190: Line 190:
return uniqueCharacters({"133252abcdeeffd", "a6789798st", "yxcdfgxcyz"})
return uniqueCharacters({"133252abcdeeffd", "a6789798st", "yxcdfgxcyz"})
end considering</lang>
end considering</lang>


===Functional===

Composing a solution from existing generic primitives, for speed of drafting and refactoring, and for high levels of code reuse.

<lang applescript>use framework "Foundation"


-------------------- UNIQUE CHARACTERS -------------------

-- uniques :: [String] -> String
on uniques(xs)
script single
on |λ|(x)
if 1 = length of x then
item 1 of x
else
{}
end if
end |λ|
end script
concatMap(single, ¬
group(sort(concatMap(my chars, xs))))
end uniques



--------------------------- TEST -------------------------
on run
uniques({"133252abcdeeffd", "a6789798st", "yxcdfgxcyz"})
--> {"1", "5", "6", "b", "g", "s", "t", "z"}
end run


------------------------- GENERIC ------------------------

-- chars :: String -> [Char]
on chars(s)
characters of s
end chars


-- 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
if {text, string} contains class of xs then
acc as text
else
acc
end if
end concatMap


-- eq (==) :: Eq a => a -> a -> Bool
on eq(a, b)
a = b
end eq


-- 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


-- group :: Eq a => [a] -> [[a]]
on group(xs)
script eq
on |λ|(a, b)
a = b
end |λ|
end script
groupBy(eq, xs)
end group


-- groupBy :: (a -> a -> Bool) -> [a] -> [[a]]
on groupBy(f, xs)
-- Typical usage: groupBy(on(eq, f), xs)
set mf to mReturn(f)
script enGroup
on |λ|(a, x)
if length of (active of a) > 0 then
set h to item 1 of active of a
else
set h to missing value
end if
if h is not missing value and mf's |λ|(h, x) then
{active:(active of a) & {x}, sofar:sofar of a}
else
{active:{x}, sofar:(sofar of a) & {active of a}}
end if
end |λ|
end script
if length of xs > 0 then
set dct to foldl(enGroup, {active:{item 1 of xs}, sofar:{}}, rest of xs)
if length of (active of dct) > 0 then
sofar of dct & {active of dct}
else
sofar of dct
end if
else
{}
end if
end groupBy


-- map :: (a -> b) -> [a] -> [b]
on map(f, xs)
-- The list obtained by applying f
-- to each element of xs.
tell mReturn(f)
set lng to length of xs
set lst to {}
repeat with i from 1 to lng
set end of lst to |λ|(item i of xs, i, xs)
end repeat
return lst
end tell
end map


-- 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


-- sort :: Ord a => [a] -> [a]
on sort(xs)
((current application's NSArray's arrayWithArray:xs)'s ¬
sortedArrayUsingSelector:"compare:") as list
end sort</lang>
{{Out}}
<pre>{"1", "5", "6", "b", "g", "s", "t", "z"}</pre>


=={{header|APL}}==
=={{header|APL}}==