0

I'm just looking for a proper and more elegant way of writing the following code in Bash:

in_array() {
local somearray=${1}[@]
local somevalue=${2}
for i in ${!somearray}; do
    if [[ ${i} == ${somevalue} ]]; then
        return 0
    fi
done
return 1
}

#declare array
declare -a myArray=(foo bar baz qux)

#defined values
val1=foo
val2=baz

#Ugly check if multiple strings are part of the array at the same time 
if in_array myArray $val1 && in_array myArray $val2; then
    # Do something #
else
    # Do something else#
fi

The basic idea is that I need to check if 2 ore more static values are, at the same time, part of the array. Wondering if there's a better way of doing this, because if I'll need to check for more than 3-4 values... that if in_array line will get huge.

Any suggestion, please?

Thank you!

6
  • 1
    Your script doesn't work. "$(foo, bar, baz, qux)" should probably have been (foo bar baz qux), $val22 should be $val2.
    – choroba
    Feb 27, 2018 at 12:59
  • @choroba - sorry.. I should have checked better the syntax when posted. You are right
    – Marin N.
    Feb 27, 2018 at 14:18
  • @Hastur - please check my question again..
    – Marin N.
    Feb 28, 2018 at 15:35
  • @MarinNedea Any suggestion, please? --> check the answers from those links... for example when they suggest =~ (for the ugliness - it's more readable ) or when they propose to flatter the array and search the substring *"two"* (you can try *$var1* && *$var1*) ... BTW I think you can agree better is really relative... :-) better to read, better because more efficient (you need to use a different function as your answer... to break the 1st time you do not find...)...?
    – Hastur
    Feb 28, 2018 at 15:48

1 Answer 1

3

Well, array operations in bash are always ugly, as shown by your own way to pass the array to the function.

I would convert your test into a for loop over the arguments which remain after assigning the array:

in_array () {
    local somearray=${1}[@]
    shift
    for SEARCH_VALUE in "$@"; do
        FOUND=false
        for ARRAY_VALUE in ${!somearray}; do
            if [[ $ARRAY_VALUE == $SEARCH_VALUE ]]; then
                FOUND=true
                break
            fi
        done
        if ! $FOUND; then
            return 1
        fi
    done
    return 0
}

so you can check for the presence of all the values in a single function call:

arr=(1 2 3 4 5)
in_array arr 1 # 0
in_array arr 1 2 # 0
in_array arr 1 6 # 1
in_array arr 1 2 3 4 5 # 0
0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .