我尝试在 Bash 中迭代关联数组。
看似简单,但是循环并没有按照数组的初始顺序
这里有一个简单的脚本可以尝试:
#!/bin/bash
echo -e "Workspace\n----------";
lsb_release -a
echo -e "\nBash version\n----------";
echo -e $BASH_VERSION."\n";
declare -A groups;
groups["group1"]="123";
groups["group2"]="456";
groups["group3"]="789";
groups["group4"]="abc";
groups["group5"]="def";
echo -e "Result\n----------";
for i in "${!groups[@]}"
do
echo "$i => ${groups[$i]}";
done
输出:
Workspace
----------
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 14.04.2 LTS
Release: 14.04
Codename: trusty
Bash version
----------
4.3.11(1)-release.
Result
----------
group3 => 789
group2 => 456
group1 => 123
group5 => def
group4 => abc
为什么我没有group1
、group2
等?
我不想要字母数字顺序,我只希望循环遵循数组的初始声明顺序...
有办法吗?
最佳答案
正如已经指出的,没有错误。关联数组以“哈希”顺序存储。如果要排序,则不要使用关联数组。或者,您使用非关联数组和关联数组。
保留第二个(非关联)数组,该数组按创建顺序标识键。然后遍历第二个数组,在打印数据时使用它的内容来键入第一个(关联)数组。像这样:
declare -A groups; declare -a orders;
groups["group1"]="123"; orders+=( "group1" )
groups["group2"]="456"; orders+=( "group2" )
groups["group3"]="789"; orders+=( "group3" )
groups["group4"]="abc"; orders+=( "group4" )
groups["group5"]="def"; orders+=( "group5" )
# Convoluted option 1
for i in "${!orders[@]}"
do
echo "${orders[$i]}: ${groups[${orders[$i]}]}"
done
echo
# Convoluted option 1 - 'explained'
for i in "${!orders[@]}"
do
echo "$i: ${orders[$i]}: ${groups[${orders[$i]}]}"
done
echo
# Simpler option 2 - thanks, PesaThe
for i in "${orders[@]}"
do
echo "$i: ${groups[$i]}"
done
PesaThe 在 comment 中建议使用“更简单的选项 2”,应该优先使用“复杂的选项”。
示例输出:
group1: 123
group2: 456
group3: 789
group4: abc
group5: def
0: group1: 123
1: group2: 456
2: group3: 789
3: group4: abc
4: group5: def
group1: 123
group2: 456
group3: 789
group4: abc
group5: def
您可能不希望这样每行有两条语句,但它强调了处理两个数组之间的并行性。
问题中作业后的分号并不是真正必要的(尽管它们不会造成积极的伤害,除了让读者想知道“为什么?”)。
关于arrays - 如何保持关联数组顺序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29161323/