Find duplicate elements in associative array with non-sequential index

I start with bash and the code as a whole and I have a lot of pain to write this, can someone tell me if it will work in each case, maybe someone has a better approach? Thank you very much in advance.

array=( [0]=24 [1]=24 [5]=10 [6]=24 [10]=24 [12]=12 )
KEYS=(${!array[@]})

for i in "${!KEYS[@]}"; do

    for j in "${!KEYS[@]}"; do

    if [[ $i -eq $j ]]; then
        continue
    fi

    if [[ ${array[${KEYS[$i]}]} -eq ${array[${KEYS[$j]}]} ]]; then

        duplicate+=( ${KEYS[$j]} )
    fi
    done

done

uniq=($(printf "%s\n" "${duplicate[@]}" | sort -u)); 

echo "${uniq[@]}"

EDIT:

my expected result is an array containing the index of duplicate elements.

+4
source share
4 answers

This approach has linear complexity (assuming a constant search for arrays by time) instead of the quadratic complexity of cascading loops:

array=( [0]=24 [1]=24 [5]=10 [6]=24 [10]=24 [12]=12 )
ref=( )

for i in "${!array[@]}"; do
    ref[array[i]]="${ref[array[i]]}$i "
done

for i in "${!ref[@]}"; do
    [[ "${ref[i]% }" == *" "* ]] && echo "$i @ ${ref[i]% }"
done

array[] ref[], ( ). ref[] :

ref=( [10]="5 " [12]="12 " [24]="0 1 6 10 " )

ref[], , , , , array[].

: , .

+4

$KEYS? $array, - . script, , , $KEYS:

array=( [0]=24 [1]=24 [5]=10 [6]=24 [10]=24 [12]=12 )

for i in "${!array[@]}"; do
    for j in "${!array[@]}"; do
        [ "$i" -eq "$j" ] && continue
        [ "${array[$i]}" -eq "${array[$j]}" ] && duplicate+=("$j")
    done
done

echo $(printf "%s\n" "${duplicate[@]}" | sort -u)

, - , echo:

echo "$(printf "%s\n" "${duplicate[@]}" | sort -u)"
+2

c-style , .

arr=( 1 2 3 4 5 6 1 2 3 4 5 6 0 1 3 )
repeats=()

for (( i=0; i < ${#arr[@]}; ++i )); do
   for (( j=i+1; j < ${#arr[@]}; ++j )); do
       if [ ${arr[i]} -eq ${arr[j]} ]; then
           repeats+=( ${arr[i]} )
            break
       fi  
   done
done

echo ${repeats[@]} | grep -o . | sort -u  
+1

:

uarr=($(for i in "${!array[@]}";do echo $i ${array[$i]}; done|awk 'a[$2]++{printf "%s ",$1}'))

:

set | grep uarr
uarr=([0]="1" [1]="6" [2]="10")
+1

Source: https://habr.com/ru/post/1532660/


All Articles