Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sqlite/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Perl 为什么将1分配给散列元素?_Perl_Perl Data Structures_Perl Hash - Fatal编程技术网

Perl 为什么将1分配给散列元素?

Perl 为什么将1分配给散列元素?,perl,perl-data-structures,perl-hash,Perl,Perl Data Structures,Perl Hash,有人能解释一下这个语句在Perl中的作用吗 $type{$_->{brand}} = 1; 我可以理解hash%类型有一个键品牌,其中包含对另一个hash品牌的引用,并为其分配了1 这是什么意思??!!!当它被指定为1时 package SillyFunction; sub group_products { my $products = shift; my %brand_type = (); my $grouped_products = []; for

有人能解释一下这个语句在Perl中的作用吗

$type{$_->{brand}} = 1;
我可以理解hash%类型有一个键品牌,其中包含对另一个hash品牌的引用,并为其分配了1

这是什么意思??!!!当它被指定为1时

package SillyFunction;

sub group_products {
    my $products = shift;
    my %brand_type = ();
    my $grouped_products = [];

    foreach (@{$products}) {
        $brand_type{ $_->{brand} } ||= {};
        $brand_type{ $_->{brand} }->{ $_->{type} } = 1;
    }

    foreach (sort keys %brand_type) {
        my $brand = $_;
        foreach (sort keys %{ $brand_type{$brand} }) {
            push(@{$grouped_products}, { brand => $brand, type => $_ });
        }
    }

    $grouped_products;
}
1;
代码

$type{$_->{brand}} = 1;
指:

我们有一个hash类型的变量,名为%hash。 主题变量$包含对散列的引用。 我们在$\引用的哈希中访问名为brand的条目。我们记住这个值。 我们使用名为%hash的哈希中刚刚记住的名称访问条目。 散列元素是左值,也就是说,可以给它们赋值。 我们将数字1分配到刚才访问的哈希槽中。 注意事项:

在Perl中,哈希是一种数据结构。其他语言将其称为关联数组。它将字符串映射到标量值。 哈希函数计算给定字符串的特征数。散列数据结构在内部使用这样的函数,并且以Perl无法访问的方式使用。散列函数在密码学中也很重要。 =运算符将右侧的对象分配给左侧的对象。 这行代码没有一个关键字,只有变量%type、$、常量'brand',1和运算符{…}、->、=;。 以下是您在评论中发布的代码,带有注释:

# Declare a namespace "SillyFunction".
# This affects the full names of the subroutines, and some variables.
package SillyFunction;

# Declare a sub that takes one parameter.
sub group_products {
  my $products = shift;

  my %brand_type = ();       # %brand_type is an empty hash.
  my $grouped_products = []; # $grouped_products is a reference to an array

  # loop through the products.
  # The @{...} "dereferences" an arrayref to an ordinary array
  # The current item is in the topic variable $_
  foreach (@{$products}) {
    # All the items in $products are references to hashes.
    # The hashes have keys "brand" and "type".

    # If the entry if %brand_type with the name of $_->{brand} is false,
    # Then we assign an empty hashref.
    # This is stupid (see discussion below)
    $brand_type{$_->{brand}} ||= {};

    # We access the entry names $_->{brand}.
    # We use that value as a hashref, and access the entry $_->{type} in there.
    # We then assign the value 1 to that slot.
    $brand_type{$_->{brand}}->{$_->{type}} = 1;
  }

  # We get the names of all entries of %brand_type with the keys function
  # We sort the names alphabetically.
  # The current key is in $_
  foreach (sort keys %brand_type) {
    # We assign the current key to the $brand variable.
    # This is stupid.
    my $brand = $_;

    # We get all the keys of the hash referenced by $brand_type{$brand}
    # And sort that again.
    # The current key is in $_
    foreach (sort keys %{$brand_type{$brand}}) {
      # We dereference the ordinary array from the arrayref $grouped_products.
      # We add a hashref to the end that contains entries for brand and type
      push(@{$grouped_products}, { brand => $brand, type => $_});
    }
  }

  # We implicitly return the arrayref containing all brands and types.
  $grouped_products;
}

# We return a true value to signal perl that this module loaded all right.
1;
这个代码是做什么的?它接受所有产品一个产品是一个包含品牌和类型字段的hashref,并主要按品牌,其次按类型,按字母顺序,升序对它们进行排序

在这样做的同时,作者产生了可怕的代码。以下是本可以做得更好的:

他使用arrayref而不是数组。只使用数组并返回对该数组的引用会更容易:

my @grouped_products;
push @grouped_products, ...;
return \@grouped_products; # reference operator \
在某个时刻,会分配一个hashref。这是不必要的,因为Perl会自动生成用作散列或数组引用的未定义值。那条完整的线是无用的。此外,仅当该值为false时才指定该值。作者可能想要的是,如果该值未定义,则赋值。定义的or运算符//只能在perl5 v10或更高版本之后在此处使用

建立了一个散列。这是浪费。数组的散列会更好。 如果使用for或foreach循环值,则不必将当前项分配给神秘的$\ux。相反,可以指定一个循环变量:foreach my$foo@bar。foreach的默认行为类似于foreach local$\uuz@bar。 隐性回报是不好的。 这里有一段代码实现了相同的子例程,但更为简单——记住,我们只是想对产品进行排序,假设它们已经是唯一的

sub group_products {
  my ($products) = @_;
  my @grouped =
    # sort by brand. If that is a draw, sort by type.
    sort { $a->{brand} cmp $b->{brand} or $a->{type} cmp $b->{type} }
    map  { +{%$_} } # make a copy.
    @$products;     # easy dereference
  return \@grouped;
}
说明:此代码主要是自文档化的。排序函数接受一个必须返回数字的块:负表示“$a小于$b”,零表示“$a和$b相等”,或正表示“$a大于$b”

cmp运算符按字母顺序比较操作数。如果品牌不同,那么我们不必比较类型。如果品牌相同,则第一个cmp返回0,这是一个假值。因此,执行第二个比较类型,并返回该值。这是按主键和辅键排序的标准Perl习惯用法

排序和映射级联从右/下到左/上执行

如果不能保证唯一性,那么这样做会更好:

use List::MoreUtils qw/uniq/;
sub group_products {
  my ($products) = @_;
  my %grouping;
  push @{ $grouping{ $_->{brand} } }, $_->{type} for @$products;
  my @grouped;
  for my $brand (sort keys %grouping) {
    push @grouped, +{brand => $brand, type => $_} for sort uniq @{ $grouping{$brand} };
  }
  return \@grouped;
}

说明:我们定义了要填充的%分组哈希。对于每个产品,我们将该产品的类型添加到分组哈希中相应品牌的arrayref中。也就是说,我们收集每个品牌的所有类型。我们定义了要填充的所有分组产品的数组。我们按字母顺序遍历所有品牌,然后按字母顺序遍历该品牌的所有独特产品。对于这些品牌/类型组合中的每一个,我们向分组产品添加一个新的hashref。uniq函数是从优秀的List::MoreUtils模块导入的。我们返回对分组产品数组的引用。

您所说的几乎没有任何意义。您是否已经完成了Perl教程?您在哪里听说过哈希函数并将某些内容分配给1?package SillyFunction;亚组产品(以下以下)产品(以下)亚组产品(以下)产品(以下)产品(以下)亚组产品(以下)产品(以下)产品(以下)亚组产品(以下)亚组产品(以下)亚组产品(以下)亚组产品(以下)产品(以下)产品(以下)产品(以下)产品(以下)产品(以下)产品(以下)产品(以下)产品(以下)产品(以下)亚组)组产品(以下)产品(以下)产品(以下)亚组产品(以下)及产品(以下)产品){{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{品牌(品牌{{{{{{{{}}}}}}}}}}}}}}品牌{{{{{{{{{{{品牌}}}}}}}}}}}}}}}}}}}}品牌.品牌}}}$products;}1;这就是我所说的代码。在代码中,$brand_type{${->{brand}}}->{${->{type}}=1;那是什么意思??!!哈希分配给数字1@WoobleNothing分配给1,1分配给哈希元素。要分解它,$u可能持有一个散列引用,因此$->{brand}正在该散列中检索与brand关联的值,然后使用i
t作为散列键来选择散列%type中的元素,该元素在此处显示为$type,因为它是正在访问的散列中的标量,并将该元素设置为1。$的使用表明这是一个循环,但由于您没有显示,我们不能确定。我可以知道为上述子例程编写一个单元测试吗。你能解释一下逻辑plz吗-amon@KuladeepParella我补充了一些解释。但是,我的函数的契约与您发布的契约相同,因此它们应该通过旧子例程的现有单元测试。进一步提示:如果您是Perl新手,您可能会喜欢。如果您最终使用了我文章的大部分内容,请记住,所有StackOverflow内容都是根据sa 3.0的cc授权的。有关详细信息,请参阅本网站的页脚。