[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: code not working ..
From: |
Greg Wooledge |
Subject: |
Re: code not working .. |
Date: |
Tue, 10 Sep 2024 19:52:04 -0400 |
On Wed, Sep 11, 2024 at 01:35:15 +0200, alex xmb sw ratchev wrote:
> hmm hard to code an args check like this ..
Are you trying to determine whether a STRING argument appears in a LIST?
I have a feeling that's what you're trying to do.
Many people think there should be some "clever" way to do this using
list-to-string serialization and delimiters.
The actual BEST way to do it is to iterate over the list, do a simple
comparison of your string against each list element, and stop if you
have a match.
Loops are not evil. Loops are your friend. You don't need to do
backflips trying to avoid writing them.
# Usage: isin stringvarname arrayvarname
# Returns 0 (true) if the string pointed to by stringvarname appears
# as an element of the array pointed to by arrayvarname. Otherwise,
# returns 1.
isin() {
local -n _isin_needle="$1" # Using namerefs means we must
local -n _isin_haystack="$2" # use ridiculous local variable names
local _isin_x # to try to avoid collisions.
for _isin_x in "${_isin_haystack[@]}"; do
[[ $_isin_needle = "$_isin_x" ]] && return 0
done
return 1
}
hobbit:~$ var=foo
hobbit:~$ arr=(a 12 foo bar)
hobbit:~$ isin var arr ; echo "$?"
0
hobbit:~$ var=fo
hobbit:~$ isin var arr ; echo "$?"
1
Of course, this function could be written in many other ways. You might
choose to pass the first argument as a value, rather than a variable
name that must be dereferenced. You might expand the array in the caller,
and pass each array element as an additional argument. These are all
reasonable choices.
What's *not* as reasonable is trying to join the array into a string with
a weird delimiter like $'\xff' before, between and after every element,
and then match that string against a pattern like *$'\ff'"$string"$'\ff'*.
I wish people would stop doing that. I know they won't, but I can dream.