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
end
Finally 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:pop
Applying 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 ].