How to keep associative array order?

后端 未结 3 607
抹茶落季
抹茶落季 2020-12-05 02:32

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 scri

3条回答
  •  天命终不由人
    2020-12-05 03:31

    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
    

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

    Sample output:

    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?').

提交回复
热议问题