如何保持关联数组的顺序? [英] How to keep associative array order?

查看:30
本文介绍了如何保持关联数组的顺序?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试在 Bash 中迭代关联数组.

I try to iterate over an associative array in Bash.

看起来很简单,但循环并不遵循数组的初始顺序.

It seems to be simple, but the loop doesn't follow the initial order of the array.

这是一个可以尝试的简单脚本:

Here is a simple script to try:

#!/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

为什么我没有 group1group2 等?

Why I don't have group1, group2, etc.?

我不想有字母顺序,我只希望循环遵循数组的初始声明顺序...

I don't want to have an alphanum order, I just want that the loop follow the initial declaration's order of the array...

有办法吗?

推荐答案

正如已经指出的,没有错误.关联数组以散列"顺序存储.如果要排序,则不要使用关联数组.或者,您可以使用非关联数组和关联数组.

As already pointed out, there is no mistake. Associative arrays are stored in a 'hash' order. If you want ordering, you don't use associative arrays. Or, you use a non-associative array as well as an associative array.

保留第二个(非关联)数组,按照键的创建顺序标识键.然后逐步遍历第二个数组,在打印数据时使用其内容键控第一个(关联)数组.像这样:

Keep a second (non-associative) array that identifies the keys in the order that they're created. Then step through the second array, using its contents to key the first (associative) array when printing the data. Like this:

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

更简单的选项 2"由 PesaThe评论,并且应该优先于复杂选项"使用.

The 'simpler option 2' was suggested by PesaThe in a comment, and should be used in preference to the 'convoluted option'.

示例输出:

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

您可能不希望这样每行有两个语句,但它强调了处理两个数组之间的并行性.

You probably don't want to have two statements per line like that, but it emphasizes the parallelism between the handling of the two arrays.

问题中分配后的分号并不是必需的(尽管它们没有任何积极的危害,只会让读者想知道为什么?").

The semicolons after the assignments in the question are not really necessary (though they do no active harm, beyond leaving the reader wondering 'why?').

这篇关于如何保持关联数组的顺序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆