January 2026

S M T W T F S
    1 23
45 678910
11121314151617
18192021222324
25262728293031

Style Credit

Expand Cut Tags

No cut tags
Sunday, August 14th, 2022 06:34 pm

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


#!/bin/bash

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

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

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

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

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

Выхлоп:


d c b a
d c b a


Эффект для меня неожиданный: в новом массиве элементы оказываются расположены в обратном порядке, то есть при добавлении нового элемента в ассоциативный массив он кладётся не в конец, после предыдущего, а в начало — перед ним! Или я что-то делаю не так, или у меня глаза на жопе, или это нигде внятно не описано, потому что ассоциативные массивы во всяких пособиях обычно упоминают скороговоркой, в man bash про порядок ключей ассоциативного массива тоже кажется ни слова.

И чё с этим делать и как с этим бороться с наименьшими затратами? А именно, когда хочется получить список именно в ожидаемом порядке по возрастанию, а не наоборот.

Sunday, August 14th, 2022 04:00 pm (UTC)
Image
Sunday, August 14th, 2022 05:40 pm (UTC)
Никогда не использовал bash, но разве для ассоциативного массива вообще имеет смысл "порядок элементов"?
А легкий гуглеж выдает: "порядок, в котором значения кодируются в ассоциативном массиве, не обязательно должен совпадать с порядком, в котором они отображаются"
Sunday, August 14th, 2022 06:20 pm (UTC)
И снова вылазит, так сказать, отказ от категориального знания :-/
Порядок (читай: отношение порядка) "правой стороны" хэш-отображения -- дело интуитивно непредсказуемое.
Edited 2022-08-14 06:21 pm (UTC)
Sunday, August 14th, 2022 06:49 pm (UTC)
Результат мышления в категориях (не прими за отсылку к сепулькам (ц) -- была у тебя простыня в духе "куды крестьянину податься", на которую Ю. Финкель ответил кратко, но в высшей степени принципиально).
Edited 2022-08-14 06:50 pm (UTC)
Sunday, August 14th, 2022 06:07 pm (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 >>> (https://stackoverflow.com/questions/29161323/how-to-keep-associative-array-order)

Однако:
---------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 (http://citforum.ru/operating_systems/manpages/SORT.1.shtml) умеет много гитик ;-)
Edited 2022-08-14 06:16 pm (UTC)
Sunday, August 14th, 2022 06:31 pm (UTC)
В bash такого способа нет, увы. Там, строго говоря, нельзя делать априорные предположения о порядке ключей в assoc-массивах. Такова плата за "вкрячивание" -- классическая Bourne shell про assoc-arrays ничего не знала.

ЗЫ Для продвинутого скриптинга я бы рекомендовал Tcl (https://tcl.tk/) (LISP-вдохновенный шелл) или newLISP (http://www.newlisp.org/) (это вообще мега-жемчужина, катастрофически недооцениваемая б***-массами, самый "человечный" и быстрейший в мире "честный" интерпретатор ЛИСПа).
Edited 2022-08-14 06:45 pm (UTC)
Sunday, August 14th, 2022 07:22 pm (UTC)
Хороший вопрос. И он распадается надвое.

Перше. Сам Тикль. Во времена моей молодости он был во всех дистрах "из коробки". Насколько я в курсе, его и сейчас можно, скажем, в Buildroot (система сборки Linux-"прошивок" на конкретную платформу -- роутеры там, кофеварки, жужжалки для ж... -- попросту говоря: большой набор Make-файлов) включением одной галочки в menuconfig заиметь. Ему (как и newLISP'у) для портирования не нужно ничего, кроме компилятора Ц и его стандартной библиотеки.

Друге. Надстройки над сабжем -- Tk (произносится "Тики" -- иксовые виджеты с машиной событий -- кстати, canvas там просто ох... какой виджет!), expect ("консольная" надстройка над Тиклем для автоматизации запуска консольных же программ), а тако ж "толстый-толстый слой" надстроек уже над ымы обоими. Тут уже "пробовать надо" (ц), в смысле: никаких гарантий нет (хотя, если в коробке есть Иксы, то и Тк скорее всего будет, хотя бы как опция).
Edited 2022-08-14 07:31 pm (UTC)
Sunday, August 14th, 2022 07:54 pm (UTC)
Пробовать надо (ц)
Навскидку предположу, что в "среднедесктопных" дистрах есть во всех, по крайней мере ядро языка (tclsh/wish).
В худшем случае портируется, опять же, с минимумом приседаний.

ЗЫ Тётя Вика: Tcl входит практически во все дистрибутивы Linux (https://ru.wikipedia.org/wiki/Tcl).
Edited 2022-08-14 08:20 pm (UTC)
Sunday, August 14th, 2022 07:50 pm (UTC)
"Интертрепаторы" Тикля и Тики зовут tclsh и wish соотв-но.
Для первоначального введения советую нагуглить уроки от кого-то из отечественных красноглазиков 90-х.
После чего современные версии (с хэш-таблицами и прочим сахаром) нечувствительно раскуриваются по http://tcl.tk/doc .
Tuesday, August 16th, 2022 01:09 pm (UTC)
А чего надо-то?
Вон, сделать один массив ключей и еще один - значений в том же самом порядке, да и всё.
ONE=(ключи тута)
TWO=(значения тута)

Цикл от нуля до длины массива-1, читаем что нужно из ONE и TWO. Чтобы вам реально была нужна скорость доступа O(1), это нужно очень много, десятки тысяч элементов, иначе - и последовательный доступ сойдет.
Hashes, как все прочие комментаторы написали, не бывают ordered по самому определению данного алгоритма. Ordered бывают массивы и деревья. Пытаться городить массив неких структур данных, равно как и деревья на, прости Господи, баше - "ну такое".

Рассказ о TCL - это интересно, да. На дворе же нынче 1987-й и на рынке труда полно знающих и желающих написанное на нем поддерживать.

Perl, Python3, Lua - в таком примерно направлении смотреть, если очень нужно.
Edited 2022-08-16 01:12 pm (UTC)
Wednesday, August 24th, 2022 05:06 am (UTC)
Так я того, не настаиваю. Можно и Python, и довольно удобно. Всякое модерновое-хипстерское (Node.js, ruby (хотя тот уже тоже из моды вышел) и чего еще там нынче есть) я нет, не стал бы разводить, ибо оно подтягивает пол-интернета хз каких пакаджей, которые тянут остальную половину интернета в качестве зависимостей, всё это кое-как ворочается, постоянно пытается звонить домой, обновляться и жаловаться на устаревшие версии, зависимости периодически сломаны и т. д.
Именно что нужно что-то такое, что встанет из стандартного для данного вида линукса пакадж-менеджера, не потянув при этом за собой всякую хрень, NetworkManager и gnome-desktop.
Tuesday, August 16th, 2022 03:38 pm (UTC)
Посчитаем строчки?
---------8><----------
!#/usr/bin/wish
button .b -text "Превед" -command {puts "Пока, козлы!"; exit}
pack .b
---------8><----------
Теперь то же самое на "этих ваших", плз ;-)
Edited 2022-08-16 03:41 pm (UTC)
Wednesday, August 24th, 2022 05:08 am (UTC)
Меряться письками бесплатно я с вами не буду, мне уже сильно больше 15 лет, к сожалению.
Wednesday, August 24th, 2022 05:23 am (UTC)
Да я и не настаиваю. Но грубить-то зачем на ровном месте?
Wednesday, August 24th, 2022 11:50 am (UTC)
Почему на ровном и почему грубить? Это занятие ("а можешь ли ты на своем любимом языке изобразить вот этакое короче моего?") именно меряньем письками и называется.
Wednesday, August 24th, 2022 07:13 pm (UTC)
А, ну, буду знать :-)
Sunday, August 14th, 2022 08:18 pm (UTC)
В гошечке, например, тоже, ассоциативные не имеют порядка и не сортируются по ключам.
Sunday, August 14th, 2022 08:35 pm (UTC)
Дык, это прямое следствие из самой сути хеширования (а большинство современных реализаций ассоков делается через хеш). Прозрачная для юзера сортировка ключей/по-ключам в некоторых языках (или библиотеках, например, STL) -- "сахар" от разработчиков.
Edited 2022-08-14 08:39 pm (UTC)