在Perl中更改数组的值

时间:2015-03-17 10:22:57

标签: arrays perl

我希望从类别价格中的数组中检索最高值,然后将该值加倍并将其保存在数组中。我的逻辑告诉我写下面这段代码:

#!/usr/bin/perl
use List::Util qw(min max);

 my @array = (
    {clothing => "Trouser", price => 40, Quantity => 2},
    {clothing => "Socks", price => 5, Quantity => 12},);

        my $maxi = max(@array);
        $name = $ {$maxi} { price };
        $name = $name * 2;
        print $name;

此代码似乎在两个值之间随机切换。如何从所述类别中获得最大值?我如何获取新值并将其替换为旧值?

5 个答案:

答案 0 :(得分:3)

来自List::Utilmax函数对数字列表进行操作,而非复杂数据结构。

您可以使用map

从结构中提取价格
my @prices = map $_->{price}, @array;
my $max    = max(@prices);

要查找相应的结构,请使用grep

my @maximal = grep $_->{price} == $max, @array;
$_->{price} *= 2 for @maximal;

(我使用了一个数组,因为可能有多个这样的元素。)

或者,不要使用max,自己在阵列上循环:

my @max_idx = 0;
for my $i (1 .. $#array) {
    my $cmp = $array[$i]{price} <=> $array[ $max_idx[0] ]{price};
    if ($cmp >= 0) {
        @max_idx = () if $cmp;
        push @max_idx, $i;
    }
}
$_->{price} *= 2 for @array[@max_idx];

答案 1 :(得分:0)

这不是你想的那个原因是因为没有散列数组这样的东西 - 那里有一个哈希引用数组

所以如果你:

print join ( "\n", @array );

你得到:

HASH(0x5a6dec)
HASH(0x133ef4c)

max不会基于此给出正确答案。

您需要做的是访问哈希的子元素。我建议最简单的方法是按价格对数组进行排序:

my @sorted = sort { $b -> {price} <=> $a -> {price} } @array;

然后 - 你最高的&#39;价格位于数组的第一个位置:

print $sorted[0] -> {price}; 

然后你可以操纵:

print $sorted[0] -> {price},"\n";
$sorted[0] -> {price} *= 2;

use Data::Dumper;
print Dumper \@sorted;

答案 2 :(得分:0)

List::Util::max不返回最大元素的索引,仅适用于数字标量。所以你必须帮助你。

use strict;
use warnings;

my @array = (
    { clothing => "Trouser", price => 40, Quantity => 2 },
    { clothing => "Socks",   price => 5,  Quantity => 12 },
);

my $maxi = 0;
for my $i ( 1 .. $#array ) {
    $maxi = $i if $array[$i]{price} > $array[$maxi]{price};
}

$array[$maxi]{price} *= 2;
for my $rec ($array[$maxi]) {
    print qq/{ ${\(join ', ', map "$_ => $rec->{$_}", sort keys %$rec)} }\n/;
}

如果您正在寻找更多舒适和奇怪的新语法。

use strict;
use warnings;
use Carp;

my @array = (
    { clothing => "Trouser", price => 40, Quantity => 2 },
    { clothing => "Socks",   price => 5,  Quantity => 12 },
);

sub maxi (@) {
    croak "Empty array" unless @_;
    my $maxi = 0;
    for my $i ( 1 .. $#_ ) {
        $maxi = $i if $_[$i] > $_[$maxi];
    }
    return $maxi;
}

my $maxi = maxi map $_->{price}, @array;
print $maxi, "\n";

$array[$maxi]{price} *= 2;
for my $rec ( $array[$maxi] ) {
    print qq/{ ${\(join ', ', map "$_ => $rec->{$_}", sort keys %$rec)} }\n/;
}

最后,您可以像List::Util::maxmap一样使用grep,因为您的所有数组成员都是指向匿名哈希的指针,因此您可以修改其内容,除非您想要将其更改为某些内容其他类型。

use strict;
use warnings;
use List::Util qw(max);

my @array = (
    { clothing => "Trouser", price => 40, Quantity => 2 },
    { clothing => "Socks",   price => 5,  Quantity => 12 },
    { clothing => "Shirt",   price => 40, Quantity => 1 },
    { clothing => "Hat",     price => 10, Quantity => 3 },
);

sub format_item {
    my $item = shift;
    local $" = ', '; # " for broken syntax highliter
    return qq({ @{[map "$_ => $item->{$_}", sort keys %$item]} });
}

my $maxprice = max map $_->{price}, @array;
my @maxs = grep $_->{price} == $maxprice, @array;

# double prices
$_->{price} *= 2 for @maxs;

print format_item($_), "\n" for @maxs;

# if you are interested in the only one
my ($max_item) = @maxs;

print format_item($max_item), "\n";

答案 3 :(得分:0)

max function&#34;返回列表中具有最高数值的条目&#34; (perldoc)。您的列表包含没有任何固有数值的哈希引用,co max无法比较它们。不幸的是,您无法为max函数提供自己的谓词。但是,您可以使用reduce函数,该函数可以被视为minmax和其他版本的更常规版本。

获得最大元素后,您可以简单地将其中一个属性乘以2(或任何其他因子)。

#!/usr/bin/perl
use List::Util qw(reduce);

my @array = (
    {clothing => "Trouser", price => 40, Quantity => 2},
    {clothing => "Socks", price => 5, Quantity => 12}
);

my $max = reduce { $a->{price} > $b->{price} ? $a : $b } @array;
$max->{price} *= 2;
print $max->{price};

答案 4 :(得分:0)

你真正想要的不是最大值,而是argmax

在您的情况下,价格是将每个项目映射到其价格的函数。您想要找到哪个元素具有最高价格。

不是哪个hashref具有最高的数字地址。你可能想要按价格对hashrefs数组进行排序,但要避免这种情况,除非出于某些其他原因需要它,因为这样做太多了。

相反,首先找到最高价格,然后grep所有价格等于最高价格的元素,以找到价格最高的所有商品(而最大值是唯一的,总是可以有多个最大化价格。也就是说, { maximum }的前映像的基数不必为1。

#!/usr/bin/env perl

use strict;
use warnings;

use List::Util qw(max);

 my @items = (
    {clothing => "Trouser", price => 40, Quantity => 2},
    {clothing => "Socks", price => 5, Quantity => 12},
    {clothing => "Shirt", price => 40, Quantity => 1},
    {clothing => "Hat", price => 10, Quantity => 3},
);

my $max_price = max map $_->{price}, @items;
my @argmax = grep $_->{price} eq $max_price, @items;

print "Items with highest price\n";
print "@{[ @{ $_ }{qw( clothing price Quantity )} ]}\n" for @argmax;

输出:

Items with highest price
Trouser 40 2
Shirt 40 1

鉴于您想要更改具有最高价格的商品的价格,您实际上想要grep这组索引。

因此,更改最后一部分以使用索引:

my $max_price = max map $_->{price}, @items;
my @argmax = grep $items[$_]->{price} eq $max_price, 0 ..  $#items;
$items[$_]->{price} *= 2 for @argmax;

print "Items with highest price\n";
print "@{[ @{ $items[$_] }{qw( clothing price Quantity )} ]}\n" for @argmax;

输出:

Items with highest price
Trouser 80 2
Shirt 80 1