Как отсортировать хеш и назначить переменную для пары ключей из массива в Perl? - PullRequest
0 голосов
/ 06 июня 2018

У меня есть такой массив

my @arr =('1','apple','2','orange','1','orange','3','berry','2','berry','1','berry');
my %hash;
my $var =1;

Теперь, как я могу отсортировать и назначить переменную для пары?Желаемый результат -

$hash{1}{apple} =>1;
$hash{1}{orange} =>1;
$hash{1}{berry} =>1;
$hash{2}{orange} =>1;
$hash{2}{berry} =>1;
$hash{3}{berry} =>1;  

Ответы [ 3 ]

0 голосов
/ 06 июня 2018

Обычно ожидается, что вы хотя бы потратите несколько часов , пытаясь самостоятельно написать решение.Мы с радостью поможем вам, если вы предприняли достойную попытку, но у вас закончились идеи, но она не сработает, если вы, кажется, сбросили свою проблему на нас и ждете ответа.пока вы пьете кружку кофе.Вам сообщили об этом до , и только один из ваших постов имеет чистый положительный голос.Над этим нужно поработать.

Вы уверены, что действительно хотите хэш хэшей?Это очень напоминает ваш предыдущий вопрос Как узнать, существует ли значение в хэше, без использования ключа в perl? , где мы в значительной степени установили, что это был неправильный выбор.

Единственный не-очевидная часть извлекает значения из массива в парах, я и я использовали цикл C-style for для достижения этого.

Я использовал Data::Dumper только для отображения результирующего хэша хэшей.

use strict;
use warnings 'all';

my @arr = qw/ 1 apple 2 orange 1 orange 3 berry 2 berry 1 berry /;

my %hash;

for ( my $i = 0; $i < $#arr; $i += 2 ) {
    $hash{$arr[$i]}{$arr[$i+1]} = 1;
}

use Data::Dumper;

print Dumper \%hash;

output

$VAR1 = {
          '2' => {
                   'berry' => 1,
                   'orange' => 1
                 },
          '3' => {
                   'berry' => 1
                 },
          '1' => {
                   'berry' => 1,
                   'orange' => 1,
                   'apple' => 1
                 }
        };

Update

Вот пример генерации ключей, как я описал в комментариях.Это почти идентично приведенному выше решению, но результирующее содержимое хеша отличается.

use strict;
use warnings 'all';

my @arr = qw/ 1 apple 2 orange 1 orange 3 berry 2 berry 1 berry /;

my %hash;

for ( my $i = 0; $i < $#arr; $i += 2 ) {
    $hash{"@arr[$i,$i+1]"} = 1;
}

use Data::Dumper;

print Dumper \%hash;

output

$VAR1 = {
          '2 berry' => 1,
          '1 apple' => 1,
          '3 berry' => 1,
          '1 orange' => 1,
          '1 berry' => 1,
          '2 orange' => 1
        };
0 голосов
/ 06 июня 2018

Возьмите значения из массива по два за раз (ключ / значение), поместите их в хеш, затем присвойте переменной значение.

use Data::Dumper;

sub SortAndAssign {
    my ($args) = @_;

    my @arr = @{$args->{ARRAY}};
    my $var = $args->{VARIABLE};

    my %hash;

    my $i = 0;
    my $size = scalar(@arr);
    while ($i < $size) {
        # alternating key/value pairs (really a hash)
        my $key = $arr[$i++];   # e.g. 1
        my $value = $arr[$i++]; # e.g. apple
        $hash{$key}{$value} = $var; # e.g. hash->1->apple = 1
    }

    return %hash;
}

sub ShowSortAndAssign {
    my @arr =('1','apple','2','orange','1','orange','3','berry','2','berry','1','berry');
    my $var = 1;

    my %hash = SortAndAssign({
        ARRAY => \@arr,
        VARIABLE => $var,
    });

    print Dumper(\%hash);
    print "first apple is " . $hash{1}{apple};
}

sub _Main {
    ShowSortAndAssign();
}

_Main();
0 голосов
/ 06 июня 2018

Вам нужно перебрать массив и вывести два значения за одну итерацию.Один из способов сделать это - использовать цикл while.Это будет использовать массив, поэтому, если вы хотите сохранить его, вы можете сделать копию.

use strict;
use warnings;
use Data::Printer;

my @arr = (
    '1', 'apple', '2', 'orange', '1', 'orange',
    '3', 'berry', '2', 'berry',  '1', 'berry',
);
my %hash;
my $var = 1;

while ( my $first_key = shift @arr ) {
    my $second_key = shift @arr;
    $hash{$first_key}->{$second_key} = $var;
}

p %hash;

Это выводит

{
    1   {
        apple    1,
        berry    1,
        orange   1
    },
    2   {
        berry    1,
        orange   1
    },
    3   {
        berry   1
    }
}

Альтернативой является использование стиля Cfor петля.Это не меняет массив.

for (my $i = 0; $i <= $#arr; $i+=2) {
    $hash{ $arr[$i] }->{ $arr[$i + 1] } = $var;
}

Или вы можете использовать List :: Util's pairs function , чтобы получить два одновременно.

use List::Util 'pairs';

foreach my $pair ( pairs @arr ) {
   my ( $first_key, $second_key ) = @$pair;
   $hash{$first_key}->{$second_key} = $var;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...