Preface
Goal: Exploring Ion Shell for string processing.
4: Approach in Solving Unique
A custom example, that you can rewrite.
An Algorithm Case
Why reinvent the wheel?
The same reason as other article.
x:xs Pattern Matching
The same with other article as well.
Exclude Function
Consider array in code below:
let tags:[str] = [ \
"60s" "jazz" "60s" "rock" \
"70s" "rock" "70s" "pop" ]The exclude function is just a filter.
ion shell has this \\= operator to diff array.
fn exclude value:str tags:[str]
let tags \\= [$value]
echo @tags
endFinally we can call them in main script.
and reformat the output using fish.
let tags_ex = [@(exclude "rock" [@tags])]
echo $join(@tags_ex :)With the result as below array:
❯ ./11-exclude.sh
60s:jazz:60s:70s:70s:pop
The ion script looks tidier than bash.
Recursive Unique Function
With exclude function above,
we can build unique function recursively, as below code:
#!/usr/bin/env ion
fn unique tags:[str]
if test $len(@tags) -le 1
echo @tags
else
let head = @tags[0]
let tail = [@tags[1..=$len(@tags)]]
let tail \\= [$head]
let uniq = [ @(unique [@tail]) ]
echo [ [$head] @uniq ]
end
end
We can also get rid of exclude function,
by using the //= operator.
Applying Unique to Simple Array
Now we can apply the method to our unique song challenge.
#!/usr/bin/env ion
let tags:[str] = [ \
"60s" "jazz" "60s" "rock" \
"70s" "rock" "70s" "pop" ]
fn exclude value:str tags:[str]
let tags \\= [$value]
echo @tags
end
fn unique tags:[str]
if test $len(@tags) -le 1
echo @tags
else
let head = @tags[0]
let tail = [@tags[1..=$len(@tags)]]
let xcld = [ @(exclude $head [@tail]) ]
let uniq = [ @(unique [@xcld]) ]
echo [ [$head] @uniq ]
end
end
echo $join(@(unique [@tags]) :)With the same result as below

With the result as below array:
❯ ./12-unique-a.sh
60s:jazz:rock:70s:popApplying Unique to data Structure
We can also apply the method to our unique song challenge.
#!/usr/bin/env ion
source ./MySongs.sh
source ./MyHelperFlatten.sh
source ./MyHelperUnique.sh
# Extract flatten output to array
let tags_nl = $(flatten [@songs])
let tags = [@split($tags_nl \n)]
echo $join(@(unique [@tags]) :)With the result as below array:
❯ ./12-unique-b.sh
60s:jazz:rock:70s:pop
What is Next 🤔?
Consider continue reading [ JQ in Bash - Playing with Records ].