Para fines académicos, aquí es una función recursiva bastante ordenada:
sub flatten_hash {
my ($hash, $path) = @_;
$path = [] unless defined $path;
my @ret;
while (my ($key, $value) = each %$hash) {
if (ref $value eq 'HASH') {
push @ret, flatten_hash($value, [ @$path, $key ]);
} else {
push @ret, [ [ @$path, $key ], $value ];
}
}
return @ret;
}
que tiene un hash como
{
roman => {
i => 1,
ii => 2,
iii => 3,
},
english => {
one => 1,
two => 2,
three => 3,
},
}
y lo convierte en una lista como
(
[ ['roman','i'], 1 ],
[ ['roman', 'ii'], 2 ],
[ ['roman', 'iii'], 3 ],
[ ['english', 'one'], 1 ],
[ ['english', 'two'], 2 ],
[ ['english', 'three'], 3 ]
)
aunque por supuesto t El orden está destinado a variar. Dada esa lista, puede ordenarla en { $a->[1] <=> $b->[1] }
o similar, y luego extraer la ruta de la clave desde @{ $entry->[0] }
para cada entrada. Funciona independientemente de la profundidad de la estructura de datos, e incluso si los nodos de hoja no ocurren todos a la misma profundidad. Sin embargo, necesita un poco de extensión para tratar con estructuras que no son puramente de hashrefs y escalares simples.
¿Desea ordenar independientemente de la profundidad dentro de la estructura? – DavidO
Hay una profundidad fija de 3 claves en este hash, y quiero ordenar el hash por el valor de todos los trillizos de claves que existen. – petranaya