Массив в стиле Hashmap в оболочке? - PullRequest
1 голос
/ 30 июня 2019

Я новичок в оболочке. Я хочу создать массив в стиле hashmap.

Я уже посмотрел на это Как определить хэш-таблицы в Bash?

Это не совсем то, что я хочу. Это то, что я ожидаю:

myArray=(emma=paris, london, ny john=tokyo, LA)

#names are my keys and cities are my values

Мой код выглядит так:

 declare -A myArray=( ["$names"]="$cities" )

Это не работает, потому что каждый новый город перезаписывает последний.

Ответы [ 3 ]

0 голосов
/ 01 июля 2019

Bash 4 поддерживает ассоциативные массивы. Но если вы используете Bash 3 или ниже, вы можете свернуть свою собственную структуру, используя обычный массив, а затем разделить каждый элемент на некоторый разделитель, такой как =.

#!/bin/bash

array=(
  emma="paris london ny" 
  john="tokyo LA"
)

for item in "${array[@]}"; do 
  key=$(cut -d "=" -f 1 <<< "$item")
  value=$(cut -d "=" -f 2 <<< "$item")
  echo "$key=$value"
done 

Пример вывода:

emma=paris london ny
john=tokyo LA
0 голосов
/ 02 июля 2019

Синтаксис declare -A arrayName=( ["key"]="value" ) должен использоваться только при намерении полностью заменить содержимое переменной , перезаписывая все ранее существующие значения, оставляя только те, которые описаны в объявлении.

Когда вы хотитесо временем добавьте новые значения, используйте arrayName["$key"]="$value".Таким образом:

declare -A arrayName=( )   # Initialize an empty associative array
arrayName["key1"]=value1   # add key1
arrayName["key2"]=value2   # add key2
arrayName["key3"]=value3   # add key3
declare -p arrayName       # print resulting array

... имеет тот же результат, что и:

# initialize with all three values already present
declare -A arrayName=( ["key1"]="value1" ["key2"]="value2" ["key3"]="value3" )
declare -p arrayName       # print resulting array

... тогда как следующее отбрасывает все, кроме последнего:

declare -A arrayName=( ["key1"]="value1" )  # initialize with key1=value1
declare -A arrayName=( ["key2"]="value2" )  # discard and overwrite with key2=value2
declare -A arrayName=( ["key3"]="value3" )  # discard and overwrite with key3=value3
declare -p arrayName                        # output only has key3 and value3!
0 голосов
/ 01 июля 2019

данасо, вы указали список городов для каждого человека или вы указали каждый город отдельно? Вещи, кажется, работают хорошо для меня, когда я делаю первое. Вот (слегка отредактированная) стенограмма моей сессии Bash:

$  declare -A myArray=([emma]="paris london ny" [john]="tokyo LA")

Или, чтобы создать свой ассоциативный массив на лету, как в вашем «реальном коде», из обычных массивов, называемых names и cities, вы сначала должны создать эти массивы, например:

$ declare -a names=(emma john)                     # Notice: small '-a' for inexed array.
$ declare -a cities=("paris london ny" "tokyo LA") # Notice: Quotes around whole lists of cities!

Тогда я бы начал с пустого myArray и собрал бы его в цикле, например:

$ declare myArray=()

for i in ${!names[@]}; do
      name=${names[$i]}
      city=${cities[$i]}
     myArray+=([$name]=$city)
done

В качестве отступления: Когда-нибудь в будущем вы, возможно, захотите заполнить myArray таким образом, но с разными записями в ваших cities и names. Если и когда вы это сделаете, это будет хорошим показателем для set -o noglob до for -циклов. Это отключает расширение имени пути оболочкой и защищает от неприятностей, когда у вас случайно есть имя или город с именем * в одном из ваших массивов. Вы можете включить его с помощью set +o noglob после for -loop.

В любом случае, независимо от того, каким образом вы будете заполнять myArray, новые города больше не будут заменять предыдущие, как вы можете видеть:

$  echo ${myArray[emma]}
paris london ny    

$ echo ${myArray[john]}
tokyo LA

И вы можете обрабатывать города по отдельности, например, в этом for -loop:

$ for city in ${myArray[emma]}; do echo "hello, $city!";  done
hello, paris!
hello, london!
hello, ny!

Как это работает для вас?

PS: Я хотел бы поблагодарить Чарльза Даффи за улучшения моего кода, которые он предложил в комментариях.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...