Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the fastest way to delete an element of an array?

Giving this array:

arr=(hello asd asd1 asd22 asd333)

I want to delete the a especific item by its value, for example asd. I did this:

IFS=' '
echo "${arr[@]/asd/}"

But it returns the following:

hello 1 22 333

So I did this function:

function remove_item() {
    local item_search="$1"
    shift
    local arr_tmp=("${@}")

    if [ ${#arr_tmp[@]} -eq 0 ]; then
        return
    fi

    local index=0
    for item in ${arr_tmp[@]}; do
        if [ "$item" = "$item_search" ]; then
            unset arr_tmp[$index]
            break
        fi
        let index++
    done

    echo "${arr_tmp[*]}"
}

arr=(asd asd1 asd22 asd333)

remove_item 'asd' "${arr[@]}"

Prints the desired output:

hello asd1 asd22 asd333

But I have to use it with very long arrays, and I have to call it a lot of times. And its performance sucks.

Do you have any better alternative to do it? Any tip, trick, or advice will be appreciatted.

like image 833
mllamazares Avatar asked Dec 31 '25 02:12

mllamazares


2 Answers

You could use a loop to iterate over the array and remove the element that matches the specified value:

for i in "${!arr[@]}"; do
  [[ "${arr[i]}" == "asd" ]] && unset arr[i]
done

If you know that the array would have at most one matching element, you could even break out of the loop:

  [[ "${arr[i]}" == "asd" ]] && unset arr[i] && break
                                            |^^^^^^^^|
                                             (this causes the loop to break
                                              as soon as the element is found)

As an example:

$ arr=(asd asd1 asd22 asd333)
$ for i in "${!arr[@]}"; do [[ "${arr[i]}" == "asd" ]] && unset arr[i]; done
$ echo "${arr[@]}"
asd1 asd22 asd333
like image 126
devnull Avatar answered Jan 03 '26 02:01

devnull


Probably @devnull's answer is fastest. But it might possibly be faster not to use a loop and instead let grep do the work. Its not very pretty though:

$ arr=(hello asd asd1 asd22 asd333)
$ remove="asd"
$ i=$(paste -d: <(printf "%s\n" "${!arr[@]}") <(printf "%s\n" "${arr[@]}") | grep -m1 -w -E "^[[:digit:]]+:${remove}$")
$ unset arr[${i%:*}]
$ 
like image 38
Digital Trauma Avatar answered Jan 03 '26 02:01

Digital Trauma



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!