Perl, преобразовать хэш в массив
Если у меня есть хеш в Perl, который содержит полные и последовательные целочисленные сопоставления (т.е. все ключи от 0 до n сопоставляются чему-то, никаких ключей за пределами этого), есть ли способ преобразования этого в массив?
Я знаю, что могу перебирать пары ключ/значение и помещать их в новый массив, но что-то говорит мне, что должно быть встроенное средство для этого.
Ответы
Ответ 1
Если исходный источник данных является хешем:
# first find the max key value, if you don't already know it:
use List::Util 'max';
my $maxkey = max keys %hash;
# get all the values, in order
my @array = @hash{0 .. $maxkey};
Или если ваш исходный источник данных является hashref:
my $maxkey = max keys %$hashref;
my @array = @{$hashref}{0 .. $maxkey};
Это легко проверить с помощью этого примера:
my %hash;
@hash{0 .. 9} = ('a' .. 'j');
# insert code from above, and then print the result...
use Data::Dumper;
print Dumper(\%hash);
print Dumper(\@array);
$VAR1 = {
'6' => 'g',
'3' => 'd',
'7' => 'h',
'9' => 'j',
'2' => 'c',
'8' => 'i',
'1' => 'b',
'4' => 'e',
'0' => 'a',
'5' => 'f'
};
$VAR1 = [
'a',
'b',
'c',
'd',
'e',
'f',
'g',
'h',
'i',
'j'
];
Ответ 2
ОК, это не очень "встроено", но работает. Он также ИМХО предпочитает любое решение, включающее "сортировку", как это быстрее.
map { $array[$_] = $hash{$_} } keys %hash; # Or use foreach instead of map
В противном случае, менее эффективно:
my @array = map { $hash{$_} } sort { $a<=>$b } keys %hash;
Ответ 3
Вы можете извлечь все значения из хэша с помощью функции values
:
my @vals = values %hash;
Если вы хотите их в определенном порядке, вы можете поместить ключи в желаемом порядке, а затем взять хэш-фрагмент из этого:
my @sorted_vals = @hash{sort { $a <=> $b } keys %hash};
Ответ 4
Perl не предоставляет встроенную систему для решения вашей проблемы.
Если вы знаете, что клавиши покрывают определенный диапазон 0..N
, вы можете использовать этот факт:
my $n = keys(%hash) - 1;
my @keys_and_values = map { $_ => $hash{$_} } 0 .. $n;
my @just_values = @hash{0 .. $n};
Ответ 5
Это оставит ключи не определены в %hashed_keys
как undef
:
# if we're being nitpicky about when and how much memory
# is allocated for the array (for run-time optimization):
my @keys_arr = (undef) x scalar %hashed_keys;
@keys_arr[(keys %hashed_keys)] =
@hashed_keys{(keys %hashed_keys)};
И, если вы используете ссылки:
@{$keys_arr}[(keys %{$hashed_keys})] =
@{$hashed_keys}{(keys %{$hashed_keys})};
Или, что более опасно, поскольку он предполагает, что вы сказали, что это правда (это может быть не всегда верно и hellip, Just sayin!):
@keys_arr = @hashed_keys{(sort {$a <=> $b} keys %hashed_keys)};
Но это похоже на точку. Если они были проиндексированы с целыми числами, то почему они теперь находятся в хеше?
Ответ 6
$Hash_value =
{
'54' => 'abc',
'55' => 'def',
'56' => 'test',
};
while (my ($key,$value) = each %{$Hash_value})
{
print "\n $key > $value";
}
Ответ 7
Как сказал DVK, нет встроенного способа, но это будет делать трюк:
my @array = map {$hash{$_}} sort {$a <=> $b} keys %hash;
или это:
my @array;
keys %hash;
while (my ($k, $v) = each %hash) {
$array[$k] = $v
}
чтобы узнать, что быстрее, я предполагаю, что это будет второй.
Ответ 8
Объединяя FM и Ether ответы позволяют избежать определения ненужного скаляра:
my @array = @hash{ 0 .. $#{[ keys %hash ]} };
Оптимальная вещь заключается в том, что в отличие от подхода scalar
, $#
работает выше даже в маловероятном случае, когда индекс по умолчанию первого элемента, $[
, отличен от нуля.
Конечно, это означало бы писать что-то глупое и обфускацию так:
my @array = @hash{ $[ .. $#{[ keys %hash ]} }; # Not recommended
Но тогда всегда есть отдаленный шанс, что кому-то это нужно где-то (вздрагивать)...
Ответ 9
@a = @h{sort { $a <=> $b } keys %h};
Ответ 10
Мы можем написать некоторое время, как показано ниже:
$j =0;
while(($a1,$b1)=each(%hash1)){
$arr[$j][0] = $a1;
($arr[$j][1],$arr[$j][2],$arr[$j][3],$arr[$j][4],$arr[$j][5],$arr[$j][6]) = values($b1);
$j++;
}
$a1 содержит ключ и
$ b1 содержит значения
В приведенном выше примере у меня есть хэш массива, а массив содержит 6 элементов.