Перебирайте ключи массива по порядку

#arrays #bash #loops

#массивы #баш #циклы

Вопрос:

это легко возможно?

У меня есть следующий код:

 for each_key in "${!myArray[@]}"
    do
        echo $each_key" : "${myArray[$each_key]}
    done
 

уверен, что это работает некорректно, но элементы отображаются не по порядку

Я стараюсь с

 IFS=$'n' orderedMyArray=($(sort <<< "${myArray[@]}"))
declare -p orderedMyArray
 

но дает мне значения, а не ключи

Комментарии:

1. Это невозможно, ассоциативные записи массива по своей сути неупорядочены. Так что вам придется сортировать их самостоятельно.

2. $each_key" : "${myArray[$each_key]} Это странное цитирование. Просто процитируй это — "$each_key : ${myArray[$each_key]}"

Ответ №1:

он работает некорректно, но элементы отображаются не по порядку

Конечно, упорядочить их по ключам тривиально — просто отсортируйте по ключам.

 for each_key in "${!myArray[@]}"; do
    echo "$each_key : ${myArray[$each_key]}" # remember to quote variable expansions!
done | sort
 

Вы можете сортировать ключи перед передачей их в for :

 for each_key in "$(printf "%sn" "${!myArray[@]}" | sort)"; do
# or funnier:
for each_key in $(IFS=$'n'; sort <<<"${!myArray[*]}"); do
# or I think I would do a while read:
keys=$(IFS=$'n'; sort <<<"${!myArray[*]}")
while IFS= read -r each_key; do ...; done <<<"$keys"
 

Комментарии:

1. Если только по порядку он не имел в виду что-то другое, кроме алфавитной сортировки. Я предполагаю, что вы правы, но в любом случае это достаточно просто. 🙂

2. большое спасибо !!!, отлично, я выберу вторые варианты, так как они ближе всего к коду

3. не знаете, почему вы «хотели бы сделать», находясь над «для-каждого-в-деле»??

4. ни то, почему вы рекомендуете заключать в кавычки выражения переменных [да, я не любитель bash]

5. why you "would do" while over for-each-in-do ?? for i in $(...) является антипаттером. Прочитайте, как читать поток построчно в bash. why you recommend to quote the variable expressions Чтобы предотвратить расширение разделения слов и расширение имени файла. Как правило, когда вы видите $ , это должно быть внутри " . кавычки

Ответ №2:

Если вы имеете в виду что-то другое, кроме сортировки самих ключей в алфавитном порядке, вы можете попробовать параллельный массив.

 $: order=( peach pear lemon lime ) # declare the order you want
$: declare -A data=( [peach]=pickled [pear]=salad [lemon]=drop [lime]=twist )
$: for k in "${order[@]}"; do echo "$k: ${data[$k]}"; done
peach: pickled
pear: salad
lemon: drop
lime: twist