Если вы не хотите N поисков, вам нужна функция hash - однако вам нужно сохранить их с этой функцией хеширования. К тому времени, когда у вас есть их в списке (или массиве), уже слишком поздно. Вам либо повезет, все время , либо у вас будет N поисков.
Или вставьте их в хеш выше ниже. Гибридным решением является сохранение локатора как элемента 0 в списке / массиве.
my $lot = get_lot_from_whatever();
my $tot = $list[0]{ $lot->{author} }{ $lot->{title} };
if ( $tot ) {
$tot->{quantity} += $lot->{quantity};
}
else {
push @list, $list[0]{ $lot->{author} }{ $lot->{title} } = $lot;
}
предыдущий
Прежде всего, мы переформатируем это, чтобы сделать его читаемым.
[ { title => 1177, author => 'ABC', quantity => '-100' }
, { title => 1177, author => 'ABC', quantity => '100' }
, { title => 1127, author => 'DEF', quantity => '5100' }
, { title => 1277, author => 'XYZ', quantity => '1030' }
]
Далее вам нужно решить проблему. Вы хотите, чтобы количество вещей сгруппировалось
по автору и названию. Так что вам нужны эти вещи, чтобы однозначно идентифицировали эти лоты.
Повторим, вы хотите, чтобы комбинация имен идентифицировала сущностей . Таким образом, вы
понадобится хеш, который идентифицирует вещи по именам.
Поскольку у нас есть две вещи, двойной хеш - хороший способ сделать это.
my %hash;
foreach my $lot ( @list ) {
$hash{ $lot->{author} }{ $lot->{title} } += $lot->{quantity};
}
# consolidated by hash
Чтобы превратить это обратно в список, нам нужно разделить уровни.
my @consol
= sort { $a->{author} cmp $b->{author} || $a->{title} cmp $b->{title} }
map {
my ( $a, $titles ) = @$_; # $_ is [ $a, {...} ]
map { +{ title => $_, author => $a, quantity => $titles->{$_} }
keys %$titles;
}
map { [ $_ => $hash{$_} ] } # group and freeze a pair
keys %hash
;
# consolidated in a list.
И вот, у тебя это есть, я даже разобрал его для тебя. Конечно, вы могли бы также
рассортируйте это по количеству издателей - по убыванию.
sort { $b->{quantity} <=> $a->{quantity}
|| $a->{author} cmp $b->{author}
|| $a->{title} cmp $b->{title}
}