Perl, конвертировать хэш в массив - PullRequest
20 голосов
/ 25 мая 2010

Если у меня есть хеш в Perl, который содержит полные и последовательные целочисленные отображения (т. Е. Все ключи от 0 до n сопоставлены с чем-то, без ключей вне этого), есть ли способ преобразовать это в массив?

Я знаю, что могу перебирать пары ключ / значение и помещать их в новый массив, но что-то подсказывает мне, что для этого должны быть встроенные средства.

Ответы [ 11 ]

21 голосов
/ 25 мая 2010

Если ваш исходный источник данных - хеш:

# 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};

Или, если ваш исходный источник данных является хеш-кодом:

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'
        ];
15 голосов
/ 25 мая 2010

Вы можете извлечь все значения из хеша с помощью функции values:

my @vals = values %hash;

Если вы хотите, чтобы они были в определенном порядке, вы можете поместить ключи в желаемом порядке и затем взять срез хеша из этого:

my @sorted_vals = @hash{sort { $a <=> $b } keys %hash};
13 голосов
/ 25 мая 2010

ОК, это не очень "встроено", но работает. Это также ИМХО предпочтительнее любого решения, включающего «сортировку», так как оно быстрее.

map { $array[$_] = $hash{$_} } keys %hash; # Or use foreach instead of map

В противном случае менее эффективно:

my @array = map { $hash{$_} } sort { $a<=>$b } keys %hash;
4 голосов
/ 25 мая 2010

Perl не предоставляет встроенного для решения вашей проблемы.

Если вы знаете, что клавиши охватывают определенный диапазон 0..N, вы можете использовать этот факт:

my $n = keys(%hash) - 1;
my @keys_and_values = map { $_ => $hash{$_} } 0 .. $n;
my @just_values     = @hash{0 .. $n};
2 голосов
/ 25 мая 2010

При этом ключи %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; Просто говори!)

@keys_arr = @hashed_keys{(sort {$a <=> $b} keys %hashed_keys)};

Но это не относится к делу. Если для начала они были целочисленными, то почему они теперь в хэше?

1 голос
/ 02 мая 2012
$Hash_value = 
{
'54' => 'abc',
'55' => 'def',
'56' => 'test',
};
while (my ($key,$value) = each %{$Hash_value})
{
 print "\n $key > $value";
}
0 голосов
/ 27 февраля 2018

Простой способ сделать @array = %hash

Например,

my %hash = (
    "0"  => "zero",
    "1" => "one",
    "2"  => "two",
    "3"  => "three",
    "4"  => "four",
    "5"  => "five",
    "6"  => "six",
    "7"  => "seven",
    "8"  => "eight",
    "9"  => "nine",
    "10"  => "ten",
);

my @array = %hash;

print "@array"; даст следующий вывод,

3 три 9 девять 5 пять 8 восемь 2 два 4 четыре 1 один 10 десять 7 семь 0 ноль 6 шесть

0 голосов
/ 20 января 2015

Мы можем написать время, как показано ниже:

$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 содержит значения В приведенном выше примере у меня есть Hash массива, и массив содержит 6 элементов.

0 голосов
/ 25 мая 2010
@a = @h{sort { $a <=> $b } keys %h};
0 голосов
/ 25 мая 2010

Объединение FM и Ether ответов позволяет избежать определения ненужного в противном случае скаляра:

my @array = @hash{ 0 .. $#{[ keys %hash ]} };

Замечательно то, что в отличие от подхода scalar, $# работает выше даже в маловероятном случае, когда индекс по умолчанию первого элемента, $[ , не равен нулю.

Конечно, это означало бы написать что-то глупое и запутанное, например:

my @array = @hash{ $[ .. $#{[ keys %hash ]} };   # Not recommended

Но тогда всегда есть отдаленный шанс , что кому-то это нужно где-то ( wince ) ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...