Я сделал это дважды в Perl.Один раз для Test :: More's is_deeply () и еще раз для perl5i's are_equal () .Делать это правильно не просто.Делать это без подпрограмм просто глупо.Если вы хотите увидеть, как это делается, посмотрите на are_equal()
, хотя это можно сделать лучше.
Но я не думаю, что вам на самом деле нужно сравнивать два хэша.
Я думаю, что происходит, вы должны проверить, присутствуют ли вещи в различных массивах в %space
.Например ...
my @arr = ('mars','earth','jupiter');
Это будет true, true и false.
my @arr1 = ('mercury','mars');
False, true.
my @arr2 = ('planet','earth','star','sun','planet2','mars');
Предполагается, что это парывсе они верны.
Я собираюсь использовать лучшие имена переменных, чем @arr
, которые описывают содержимое, а не тип структуры.Я также собираюсь предположить, что use strict; use warnings; use v5.10;
присутствует.
Первые два просты, перебрать массив и проверить, есть ли запись в %space
.И мы можем сделать оба массива за один цикл.
for my $name in (@names1, @names2) {
print "$name...";
say $space{$name} ? "Yes" : "No";
}
Третий набор немного сложнее, и то, как данные размещены, усложняет его.Вводить пары в список неудобно, для этого и нужны хэши.Это будет иметь больше смысла ...
my %object_types = (
earth => "planet", sun => "star", mars => "planet2"
);
Тогда это легко.Убедитесь, что $space{$name}{$type}
истинно.
for my $name (keys %object_types) {
my $type = $object_types{$name};
print "$name / $type...";
say $space{$name}{$type} ? "Yes" : "No";
}
Или, если вы застряли с массивом, мы можем перебрать список попарно.
# $i will be 0, 2, 4, etc...
for( my $i = 0; $i < $#stellar_objects; $i+=2 ) {
my($type, $name) = ($stellar_objects[$i], $stellar_objects[$i+1]);
print "$name / $type...";
say $space{$name}{$type} ? "Yes" : "No";
}
Что если у вас есть хештипов с несколькими именами для проверки вместо этого?
my %object_types = (
planet =>['earth'],
star =>['sun'],
planet2 =>['earth','mars']
);
Та же идея, но нам нужен внутренний цикл над массивом имен.Правильное использование имен переменных множественного числа помогает не усложнять ситуацию.
for my $type (keys %object_types) {
my $names = $object_types{$type};
for my $name (@$names) {
print "$name / $type...";
say $space{$name}{$type} ? "Yes" : "No";
}
}
Поскольку это действительно набор пар для поиска, объединение их в большой хеш является плохой услугой.Лучшей структурой данных для этого поиска может быть список пар.
my @searches = (
[ planet => 'earth' ],
[ star => 'sun' ],
[ planet2 => 'earth' ],
[ planet2 => 'mars' ],
);
for my $search (@searches) {
my($type, $name) = @$search;
print "$name / $type...";
say $space{$name}{$type} ? "Yes" : "No";
}
Для записи, %space
плохо спроектирован.Первые два уровня хороши, имя и тип, это странные хеши, которые неудобны.
'sun'=>{
'star' =>{
# This part
'1' =>'US',
'2' =>'UK'
}
},
Это не имеет ни одного из преимуществ хэша, и всех недостатков.Преимущество хеша в том, что он очень быстро ищет один ключ, но это делает его неловким, делая интересную часть ценным.Если ключ пытается наложить порядок на хеш, используйте массив.
sun => {
star => [ 'US', 'UK' ]
},
Тогда вы можете получить список стран: $countries = $space{$name}{$type}
Если вы хотите быстрый поиск ключаи порядок не имеет значения, используйте хеш с ключами, являющимися сохраненной вещью, и значением, равным 1 (просто заполнитель для «true»).
sun => {
star => { 'US' => 1, 'UK' => 1 }
},
Это использует преимущества поиска ключа хеша ипозволяет $space{$name}{$type}{$country}
быстро проверить наличие.«Значения» (даже если они хранятся в виде ключей) также гарантированно будут уникальными.Это формально известно как set , набор уникальных значений.
И вы можете хранить дополнительную информацию в значении.