Порядок элементов а ассоциативном массиве bash

Aug 14, 2022 18:34


Народ, чего-то я или не понимаю, или туплю. Вот такой пример на bash'е:
Read more... )

linux, вопрос залу, компьютеры, bash

Leave a comment

Comments 25

armagedon_tvp August 14 2022, 16:00:11 UTC

... )

Reply


andrey_chuprov August 14 2022, 17:40:42 UTC
Никогда не использовал bash, но разве для ассоциативного массива вообще имеет смысл "порядок элементов"?
А легкий гуглеж выдает: "порядок, в котором значения кодируются в ассоциативном массиве, не обязательно должен совпадать с порядком, в котором они отображаются"

Reply

alex_dragon August 14 2022, 18:08:06 UTC
> но разве для ассоциативного массива вообще имеет смысл "порядок элементов"?

А вы попробуйте выбрать последовательно все элементы такого массива. Окажется, что какой-то порядок должен быть. Кроме того, в баше массив - это в общем-то просто текстовая строка, в которой какие-то значащие наборы символов разделены пробельными символами. А такая строка - это всегда определённая последовательность. В баше есть только одномерные массивы и часто для всяких трюков используются не значения, а именно ключи, и их порядок может иметь значение.

Reply

rexy_craxy August 14 2022, 18:20:49 UTC
И снова вылазит, так сказать, отказ от категориального знания :-/
Порядок (читай: отношение порядка) "правой стороны" хэш-отображения -- дело интуитивно непредсказуемое.

Reply

alex_dragon August 14 2022, 18:44:23 UTC
Переведи. :-) Что такое «категориальное знание»?

Reply


Есть такое дело rexy_craxy August 14 2022, 18:07:10 UTC
If you want ordering, you don't use associative arrays. Associative arrays are stored in a 'hash' order. If you want ordering, you don't use associative arrays >>>

Однако:
---------8><------------

#!/bin/bash

# Создаём обычный индексированный массив
one=("a" "b" "c" "d")

# Объявляем ассоциативный массив
declare -A two

# В новом массиве в качестве ключей и значений
# используем значения из исходного массива
for i in "${one[@]}"
do
two["$i"]="$i"
done

# Выводим список ключей
echo "${!two[@]}"

# Выводим содержимое нового массива
echo "${two[@]}"

#------------------------------------
#
# THE SOLUTION:
#
for k in $(for k in "${!two[@]}"; do echo $k; done | sort); do
echo "two[$k] = ${two[$k]}"
done---------8><------------

Ну, и не забываем, что sort умеет много гитик ;-)

Reply

Re: Есть такое дело alex_dragon August 14 2022, 18:21:22 UTC
Дык с сортом каждый дурак сумеет. :-D) А sort у нас вроде к built-in не относится, следовательно вызов в цикле внешней команды - это такое, не кошерное, только в крайнем случае. Я думал, может слона не приметил и есть какой-то стандартный и вменяемый способ без колдовства.

Reply

Re: Есть такое дело rexy_craxy August 14 2022, 18:31:40 UTC

В bash такого способа нет, увы. Там, строго говоря, нельзя делать априорные предположения о порядке ключей в assoc-массивах. Такова плата за "вкрячивание" -- классическая Bourne shell про assoc-arrays ничего не знала.

ЗЫ Для продвинутого скриптинга я бы рекомендовал Tcl (LISP-вдохновенный шелл) или newLISP (это вообще мега-жемчужина, катастрофически недооцениваемая б***-массами, самый "человечный" и быстрейший в мире "честный" интерпретатор ЛИСПа).

Reply

Re: Есть такое дело alex_dragon August 14 2022, 19:02:50 UTC
Как-нибудь надо tcl поинтересоваться. Но тут по ходу интересный вопрос возникает: какова вероятность что он по умолчанию из коробки в наугад взятом дистре устанавливается?

Тут ведь от назначения и возможного применения много зависит. Одно дело когда можешь тянуть какие хочешь зависимости, другое - когда дай бог чтобы хотя бы coreutils стояли.

Reply


lefantasy August 14 2022, 20:18:27 UTC
В гошечке, например, тоже, ассоциативные не имеют порядка и не сортируются по ключам.

Reply

rexy_craxy August 14 2022, 20:35:40 UTC
Дык, это прямое следствие из самой сути хеширования (а большинство современных реализаций ассоков делается через хеш). Прозрачная для юзера сортировка ключей/по-ключам в некоторых языках (или библиотеках, например, STL) -- "сахар" от разработчиков.

Reply


Leave a comment

Up