× К оглавлению На главную Об авторе
## 1. Назначение Ассоциативные массивы [были введены](https://stackoverflow.com/a/14371026/24648605) в Bash начиная с 4-й версии и [позволяют](https://tldp.org/LDP/abs/html/bashver4.html#FTN.AEN21025) связывать два списка: * первый содержит данные, * второй - ключи, индексирующие отдельные элементы массива данных. Они, ассоциативные массивы, так же [известные](https://labex.io/tutorials/shell-how-to-assign-associative-arrays-to-ordered-pairs-in-bash-392970) как хэш-таблицы(hash tables) или словари(dictionaries) являются мощным средством в Bash, которые позволяют хранить и манипулировать данными в формате ключ-значение. Непохожие на традиционные массивы, использующие числовую индексацию, они обладают следующими навыками, чтобы писать краткие и эффективные скрипты: ┌─────────────────────────────────────┐ ┌───────────────┐ │ Как назначается ассоциативный массив├─┬─┤ Декларация ├────┐ │ для упорядочивания пар в Bash │ │ │ переменных │ │ ┌───────────────┐ └─────────────────────────────────────┘ │ └───────────────┘ ├────┤ Обработка ├──┐ │ ┌───────────────┐ │ │ переменных │ │ ├─┤ Использование ├────┘ └───────────────┘ │ │ │ переменных │ │ │ └───────────────┘ ┌───────────────┐ │ │ ┌───────────────┐ │ Управление │ │ ┌─────────┐ ├─┤ Утверждение ├─────────┤ потоком ├──┼──┤ Shell │ │ │ if-else │ └───────────────┘ │ └─────────┘ │ └───────────────┘ ┌───────────────┐ │ │ ┌───────────────┐ │ Продвинутые │ │ └─┤ Чтение данных ├─────────┤ концепции ├──┘ │ (ввод данных) │ │ сценариев │ └───────────────┘ └───────────────┘ С практической точки зрения ассоциативные массивы полезны, когда необходио сохранять повторяющиеся данные и связывать списки, что является неподъемным для обычной числовой индексации. А именно, сохранение конфигурационной, пользовательской информации или иных данных, хранение которых может быть эффективно организовано с использованием ключ значения. В контексте Bash-программирования, упорядочивание пар является комбинацией двух значений, которые трактуются как единое целое. Упорядоченные пары часто используются для представления координатных точек, ассоциаций ключ-значения или других данных, которые могут быть эффективно организованы внутри пар. Упорядоченная пара в Bash обычно представлена строкой, где два значения отделены разделителем, такими как запятая или двоеточие. Для примера пара координат (x, y) может быть представлена как "x,y" или "x:y". При этом, по-мимо упорядоченных пар, ключ ассциотивного массива может включать символы пробелов, или функциональные и/или хвостовые пробелы . Однако, запрещено использовать только одни символы, разделяющий слова, не отображаемые в виде знака. ## 2. Использование ### 2.1 Декларация #### 2.1.2 Упорядочиванной пары

    pair="1,0"

Представляет собой просто текстовую строку "1,10", содержащую одну упорядоченную пару :

   echo "$pair"

#### 2.1.2 Несколько упорядочнных пар Осуществляется с помощью ассоциативного массива, например, двумерной матрицы :

    declare -A mpairs

    mpairs["$pair"]="c"
    mpairs+=(["0,0"]="a",["0,1"]="b",["1,1"]="d")

Декларация ассоциативного массива осуществляется с помощью ```declare -A```, которая в текущем потоке декларирует переменную mpairs, являющейся симуляцией 2D ассоциативного массива, [Associative 2D Array Simulation](https://www.baeldung.com/linux/bash-2d-arrays) :

      col/line 0       1
             ┌───┐ │ ┌───┐
           0 │ а │ │ │ b │
             └───┘ │ └───┘
            ───────┼───────
             ┌───┐ │ ┌───┐
           1 │ c │ │ │ d │
             └───┘ │ └───┘

Доступ ко всем элементам ассоциативного массива осуществляется :

     echo "${mpairs[@]}"

Вывод ключей :

     echo "${!mpairs[@]}"

К единичному :

     mpairs["1,1"]="x"

#### 2.2 Сериализация/Десериализация Если код декларации и доступа разбить по разным функциям, необходимо [использовать](https://stackoverflow.com/a/55317015/24648605) "сериализацию к временному файлу", что конечно накладывает свои ограничения по использвоанию, но иногда достаточно хорошо работает:

    ## Declare Associative 2D Array Simulation
    a2darr(){
      declare -A mpairs
      pair="1,0"
      mpairs["$pair"]="c"
      mpairs+=(["0,0"]="a" ["0,1"]="b" ["1,1"]="d")
      # declare -p can be used to dump the definition
      # of a variable as shell code ready to be interpreted
      declare -p mpairs > "${serialized_array}" #  serialize an array in temporary file
      printf "Declare Associative 2D Array Simulation: " 
      for pair in "${!mpairs[@]}" ;
      do  
         printf "%s " "${mpairs[${pair}]}"
      done
      echo 
      # perform cleanup after finishing script
      cleanup() {
         if [ -f "${serialized_array}" ] ; then
            printf "to cleanup the serialized array [%s]\n" "${serialized_array}"
            rm "${serialized_array}"
         fi
         unset serialized_array
      }
      trap cleanup EXIT
    }

Десериализацию массива следует производить в точке применения :

    ## outputing all values have representing additional data associated with 
    ## each pair
    a2darr-data(){ 
      source "${serialized_array}"  # deserialize an array
      for pair in "${!mpairs[@]}" ; 
      do 
        printf "%s " " ${mpairs[${pair}]}"
      done
      echo
      ## to be outputed: b a c d 
    }

### 2.3 Cортировка Сортировка ассоциативного массива [легко применить](https://stackoverflow.com/a/8217375/24648605) с помощью команды sort :

    a2darr-data-sort(){
    printf "Sorting all values are associated with ordered pairs: "
    source "${serialized_array}"  # deserialize an array
    for pair in "${!mpairs[@]}" ; 
       do 
          echo "${mpairs[${pair}]} "
       done |
    sort -d |
    tr "\n" " "  
    echo 
    }

Здесь команда tr убирает символы новой строки на выводе команды echo , чтобы получить вывод в одну строку:

    Sort all values are associated with ordered pairs: a  b  c  d  

### 2.4 Утверждение if-else В данном случае, используется для определения выхода за пределы обасти видимости 2D ассоциативного массива :

    E_2DARR=99    # Error code for missing entry.

    # fetch a value by an ordered pair to pass in $1
    a2darr-fetch-value(){
      source "${serialized_array}"  # deserialize an array
      if [[ -z "${mpairs[$1]}" ]]
      then
        echo "$1's pair is not in 2D array."
        return $E_2DARR
      fi
      echo "$1's pair is ${mpairs[$1]}."
      return $?
    }

Результат проверки упорядоченных пар 1,0 и 2,0:

    a2darr-fetch-value "1,0"   # output: 1,0's pair is c.
    a2darr-fetch-value "2,0"   # output: 2,0's pair is not in 2D array.

### 2.5 Пробельные и функциональные символы Функциональный массив так же можно использовать при чтении ввода данных, например, [последовательностей функциональных клавишь](https://www.linuxquestions.org/questions/programming-9/bash-case-with-arrow-keys-and-del-backspace-etc-523441/#post3793948) :

    declare -A funckeys 

    funckeys=(
    ["0"]="Enter"
    ["27 91 65 "]="up"
    ["27 91 66 "]="down"
    ["27 91 67 "]="right"
    ["27 91 68 "]="left")

    printf "\nEsc-sequence:> "
    while IFS='^B' read -sn1 -t3 a # ^B is Control B
    do
      k=`perl -e "printf('%d',ord('$a'));"`
      printf "%s " "$k"
      pair+="$k "
    done
    echo
    if [[ -n "${funckeys[${pair}]}" ]] ; then
      printf "Entered funckeys: %s\n" "${funckeys[${pair}]}"
    else
      printf "Entered funckeys: %s\n" "not reconized"
    fi

Нажатие стрелки вверх :

    Esc-sequence:> 27 91 65 
    Entered funckeys: up

Нажатие Enter :

    Esc-sequence:> 0 
    Entered funckeys: not reconized

Распознование использование ассоцианированного массив при чтение данных (ввод данных) позволяет создавать продвинутые концепции сценариев совместно с управлением потока с помощью утверждения if-else .