2013-10-09 3 views
7

В zsh существует ли способ присвоить ассоциативный массив другой переменной? Я хотел бы, чтобы что-то вроде этого:Как назначить ассоциативный массив другой переменной в zsh?

typeset -A orig 
orig=(key1 val1 key2 val2) 
typeset -A other 
other=$orig 
print '$orig: '$orig 
print '$other: '$other 
print '$orig[key1]: '$orig[key1] 
print '$other[key1]: '$other[key1] 

Это будет печатать:

$orig: val1 val2 
$other: val1 val2 
$orig[key1]: val1 
$other[key1]: 

Я хочу, чтобы иметь возможность использовать $other[key1] и получить val1.

Я знаю, что могу перебирать ключи и копировать их по элементам, но я действительно хочу этого избежать. Кроме того, eval зло :)

Я попытался other=($orig) и другие варианты, но это будет получить мои ценности от orig и создать в ассоциативный массив как это

other=(val1 val2) 

Так other[key1] возвращает ничего и other[val1] возвращается val2, что я не хочу.

Если я правильно понимаю, что происходит в каждой попытке шахты является то, что $other получает массив значений из $orig, без ключей. Как я могу заставить его получать оба ключа и значениями и иметь правильную связь между ними?

Я не беспокоюсь о нулевых значениях, если это было бы проблемой, , потому что я уверен, что $orig будет хорошо себя вести.

Спасибо!

ответ

10

Вы должны вникать в чудесный мир флажков расширения параметров :) Флаги k и v могут использоваться вместе, чтобы заставить ассоциативный массив расширяться как своими ключами, так и значениями.

$ typeset -A orig 
$ orig=(key1 val1 key2 val2) 
$ print ${(kv)orig} 
key1 val1 key2 val2 

Затем вы можете использовать команду set для заполнения копии с ключом/значений переменных, полученных этим расширением.

$ typeset -A other 
$ set -A other ${(kv)orig} 
$ print $other[key1] 
val1 

Эти и другие флаги описаны в man zshexpn разделе «Параметр расширение Flags», который является одним из моих любимых zsh особенностей.

+0

Спасибо, что решил мою проблему! Единственное, что я не понимаю, - это то, что нужно «set -A». Я пробовал без него, и это сработало. Кроме того, извините за то, что вы не повышаете, я пытался, но у меня недостаточно репутации. –

+0

В примере, который я нашел, используется 'set -A', но я думаю, что это просто альтернатива' other = ($ {(kv) orig}) '. – chepner

+0

О, я вижу, спасибо! –

2

zsh: bad set of key/value pairs for associative array

Идеальный мир без побега:

➜ typeset -A old new 
➜ old=(k1 v1 k2 v2 k3 v3) 
➜ typeset old # old=(k1 v1 k2 v2 k3 v3) 

... не существует, и ваши массивы, как правило, включают в себя пустые значения:

➜ old[k2]= 
➜ typeset old # old=(k1 v1 k2 '' k3 v3) 

...Поэтому вам нужно использовать " (квотирование), @ (побег) и f (разделительный поле):

➜ typeset new # new=() 
➜ new=("${(@fkv)old}") 
➜ typeset new # new=(k1 v1 k2 '' k3 v3) 

См man zshexpn больше на флагах расширения параметров.

Смежные вопросы