Замена повторяющихся элементов в массиве

avatar
QwertyBot
1 июля 2021 в 18:32
60
1
1

Я новичок в написании сценариев bash, и мне нужна помощь в решении моей задачи... У меня есть массив:

arr=( one two tree four five six seven one  four  nine one  two  one  ten )

Мне нужно изменить его на правило: Если элемент повторяется в первый раз, добавьте 1 в конец, если дважды - 2.

Ожидаемый результат:

arr=( one two tree four five six seven one1 four1 nine one2 two1 one3 ten )

Мой код:

for i in ${!arr[*]}
do
    k=1
    for j in ${!arr[*]}
        do
        if [[ ( ${arr[$i]} = ${arr[$j]} ) && ( $i > $j )  ]] ;then
            arr[$i]=$(echo ${arr[$j]}$k)
            ((j++))
            ((k++))
        fi
    done
    echo ${arr[$i]}
    ((i++))
done

Пожалуйста, дайте мне совет, как решить эту задачу...

Источник

Ответы (1)

avatar
Barmar
1 июля 2021 в 18:57
2

Используйте ассоциативный массив для хранения текущего количества слов.

declare -A count
for i in ${!arr[*]}
do
    if [[ -n "${count[${arr[$i]}]}" ]]
    then 
        ((count[${arr[$i]}]++))
        arr[$i]=${arr[$i]}${count[${arr[$i]}]}
    else
        count[${arr[$i]}]=0
    fi
done
QwertyBot
2 июля 2021 в 07:29
0

все количество будет 1 в вашем решении

Barmar
2 июля 2021 в 07:30
0

Почему? ((count[$arr[$i]]++)) увеличивает счетчик при каждом использовании.

QwertyBot
2 июля 2021 в 07:34
0

когда я делаю echo ${count[*]}, он содержит только 1 1 1 .....

Barmar
2 июля 2021 в 08:23
0

Я исправил проблемы.

KamilCuk
2 июля 2021 в 09:21
0

Более короткая версия: for i in ${!arr[*]}; do ((count[${arr[$i]}]++)) && arr[$i]+=$((count[${arr[$i]}]-1)); done

Barmar
2 июля 2021 в 09:27
0

@KamilCuk короче != лучше

QwertyBot
8 июля 2021 в 08:12
0

@Barmar Пожалуйста, не могли бы вы объяснить еще одну вещь. Что мне делать, если я ожидаю следующий результат: arr=(один0 два1 три четыре3 пять шесть семь один7 четыре8 девять один10 два11 один12 десять) где числовой индекс повторяющегося элемента

Barmar
8 июля 2021 в 14:26
0

Это совсем другое. Вы должны пройти через массив дважды. Первый проход обнаруживает все повторяющиеся элементы, второй проход добавляет к ним индекс.