0

I have a function to check if something is in an array:

function inArray() {
    local val="$1"
    shift
    local array=("$@")
    for i in "${array[@]}"; do
        if [ "${i}" == "${val}" ]; then
            return 0
        fi
    done
    return 1
}

And an if statement to try to insert values into noDupe only if it doesn't already have that value:

noDupe=()
values=("test" "test" "test2")
for value in ${values[@]}; do
    if [ $(inArray "${value}" "${values[@]}") -eq 1 ]; then
        noDupe+="{value}"
    fi
done

My current error is that -eq expects a unary operator. I've tried changing it to a == but that's just for strings and not the 0s and 1s my function is returning. How can I get the if statement to work?

3 Answers 3

1

Your function is using return values, but you're trying to use it as it if the return values were printed. The correct usage for "if the exit status is non-zero" simplifies to

if ! inArray "${value}" "${values[@]}"; then

Side note: the error you're getting is not that -eq expects a unary operator, it's

bash: [: -eq: unary operator expected

meaning that [ expected a unary operator, but instead it got -eq, a binary operator. This is because your command substitution is unquoted, and when the command returns nothing, your test becomes

[ -eq 1 ]

With proper quoting,

[ "$(inArray "${value}" "${values[@]}")" -eq 1 ]

the test would complain that it expects an integer expression (but gets the empty string instead), because it expands to

[ "" -eq 1 ]
Sign up to request clarification or add additional context in comments.

Comments

1

The array search function can become a bottleneck if the array length is large. As an alternative consider using bash associative array. It will simplify the code, and speed up execution - reducing the complexity from O(n^2) to O(n log n).

The no-dup logic can be implemented without having to write the inArrayfunction.

declare -A v_temp
values=("test" "test" "test2")
for value in ${values[@]}; do
    v_temp[$value]=1
done
noDupe=(${!v_temp[@]})

Comments

0

Consider this method using $BASH_REMATCH:

inArray () {
    re="_S_$1 | $1 | ${1}_E_"
    [[ "_S_${array[@]}_E_" =~ $re ]] && return 0 || return 1
}

And array name could be also send as arg to this function:

inArray () {
    name="$1[@]"
    re="_S_$2 | $2 | ${2}_E_"
    [[ "_S_${!name}_E_" =~ $re ]] && return 0 || return 1
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.