arrays - una - ¿Cómo mantener el orden de matrices asociativas?
vector equiespaciado matlab (2)
Como ya se ha señalado, no hay error. Las matrices asociativas se almacenan en un orden ''hash''. Si desea ordenar, no utiliza matrices asociativas. O bien, utiliza una matriz no asociativa, así como una matriz asociativa.
Mantenga una segunda matriz (no asociativa) que identifique las claves en el orden en que se crearon. Luego pase a través de la segunda matriz, utilizando su contenido para ingresar la primera matriz (asociativa) al imprimir los datos. Me gusta esto:
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
La ''opción más simple 2'' fue sugerida por PesaThe en un comment , y se debe usar con preferencia a la ''opción complicada''.
Salida de muestra:
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
Probablemente no quieras tener dos afirmaciones por línea así, pero enfatiza el paralelismo entre el manejo de las dos matrices.
Los puntos y coma después de las asignaciones en la pregunta no son realmente necesarios (aunque no causan un daño activo, más allá de dejar al lector preguntándose "¿por qué?").
Intento iterar sobre una matriz asociativa en Bash.
Parece ser simple, pero el bucle no sigue el orden inicial de la matriz.
Aquí hay un script simple para probar:
#!/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
La salida:
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
¿Por qué no tengo group1
, group2
, etc.?
No quiero tener un orden alfanum, solo quiero que el bucle siga el orden de la declaración inicial de la matriz ...
¿Hay alguna manera?
Otra forma de ordenar las entradas en su matriz asociativa es mantener una lista de los grupos a medida que los agrega como una entrada en la matriz asociativa. Llame a esta clave de entrada "group_list". A medida que agregue cada nuevo grupo, agréguelo al campo group_list, agregando un espacio en blanco para separar las adiciones posteriores. Aquí hay uno que hice para una matriz asociativa que llamé master_array:
master_array["group_list"]+="${new_group}";
Para secuenciar a través de los grupos en el orden en que los agregó, secuencia a través del campo group_list en un bucle for , luego puede acceder a los campos de grupo en la matriz asociativa. Aquí hay un fragmento de código para uno que escribí para master_array:
for group in ${master_array["group_list"]}; do
echo "${group}";
echo "${master_array[${group},destination_directory]}";
done
y aquí está la salida de ese código:
"linux"
"${HOME}/Backup/home4"
"data"
"${HOME}/Backup/home4/data"
"pictures"
"${HOME}/Backup/home4/pictures"
"pictures-archive"
"${HOME}/Backup/home4/pictures-archive"
"music"
"${HOME}/Backup/home4/music"
Esto es similar a la sugerencia de Jonathan Leffler, pero mantiene los datos con la matriz asociativa en lugar de tener que mantener dos matrices separadas. Como puede ver, no está en orden aleatorio, ni en orden alfabético, sino en el orden en que los agregué a la matriz.
Además, si tiene subgrupos, puede crear listas de subgrupos para cada grupo y también secuenciarlas. Esa es la razón por la que lo hice de esta manera, para aliviar la necesidad de múltiples arreglos para acceder al conjunto asociativo, y también para permitir la expansión a nuevos subgrupos sin tener que modificar el código.
EDITAR: corregir algunos errores tipográficos