通过hash-PERL进行计数

通过hash-PERL进行计数,perl,hash,count,Perl,Hash,Count,我有一个数据库的地方,人们订购的项目。我分析了这个列表,得到了城市和州,所以它像这样打印-城市,州(纽约,纽约)等等 我使用变量$city和$state,但我想计算每个城市和州出现的次数,所以看起来像这样-城市,州,计数(西雅图,华盛顿州8) 除了伯爵外,我所有的东西都能用。。我正在使用哈希,但我无法找出此哈希的错误: if ($varc==3) { $line =~ /(?:\>)(\w+.*)(?:\<)/; $city = $1; }

我有一个数据库的地方,人们订购的项目。我分析了这个列表,得到了城市和州,所以它像这样打印-城市,州(纽约,纽约)等等

我使用变量$city和$state,但我想计算每个城市和州出现的次数,所以看起来像这样-城市,州,计数(西雅图,华盛顿州8)

除了伯爵外,我所有的东西都能用。。我正在使用哈希,但我无法找出此哈希的错误:

if ($varc==3) {
        $line =~ /(?:\>)(\w+.*)(?:\<)/;
        $city = $1;
    }
    if ($vars==5) {
        $line =~ /(?:\>)((\w+.*))(?:\<)/;
        $state = $1;

        # foreach $count (keys %counts){
        #   $counts = {$city, $state} {$count}++;
        #   print $counts;
        # }

    print "$city, $state\n";

    }

不必打印城市和州,您可以使用这两个项目构建一个“位置”字符串,并使用以下计数代码:

# Declare this variable before starting to parse the locations.
my %counts = ();

# Inside of the loop that parses the city and state, let's assume
# that you've got $city and $state already...

  my $location = "$city, $state";
  $counts{$location} += 1;
}

# When you've processed all locations then the counts will be correct.
foreach $location (keys %counts) {
  print "OK: $location => $counts{$location}\n";
}

# OK: New York, NY => 5
# OK: Albuquerque, NM => 1
# OK: Los Angeles, CA => 2

这将是一个答案和代码审查的组合。我将从一个警告开始

您正在尝试用正则表达式解析看起来像XML的内容。虽然改用现有的解析器

我怎么知道?尖括号之间的内容看起来像是XML格式,除非您有一个非常奇怪的CSV文件

#             V            V
$line =~ /(?:\>)(\w+.*)(?:\<)/;
为什么有两个捕获组,都捕获相同的东西


无论如何,您要计算每个州和城市组合出现的频率

你运行过这个代码吗?即使没有严格的,也会出现语法错误。我甚至不知道它应该做什么,所以我不能告诉你如何修复它

要实现计数,您需要一个散列。你说得对。但是您需要在文件读取循环之外声明该散列变量。然后,您需要在散列中为您的城市和州组合创建一个键,并在每次看到该组合时递增该键

my %counts;    # declare outside the loop
while ( my $line = <$fh> ) {
    chomp $line;
    if ( $varc == 3 ) {
        $line =~ /(?:\>)(\w+.*)(?:\<)/;
        $city = $1;
    }
    if ( $vars == 5 ) {
        $line =~ /(?:\>)((\w+.*))(?:\<)/;
        $state = $1;

        print "$city, $state\n";

        $count{"$city, $state"}++;    # increment when seen
    }
}

至少,你需要向我们展示你正在使用的散列的结构。我想这就是我所做的…这真的不是很清楚。您可以向我们显示构建
%counts
的代码,或者使用Data::Dumper向我们显示内容的外观。我们也不这样做。您说您正在解析列表。向我们展示进行解析的代码。我不明白[at]places=(后跟城市和州)是如何得到的。我有一段代码,在运行时会打印城市和州,但不会打印[at]位置和这种类型的列表,因此我不知道如何在[at]之后格式化列表地方…除非我复制粘贴所有这些并手动制作列表,但这似乎完全违背了你说的“解析列表以获取城市和州”的目的听起来你已经有了一个包含数组中那些解析项的列表。如果是这样的话,那么你所需要做的就是之后剩下的代码。嗯……所以当我运行上面列出的完整代码时,它点击了print$city$state行(没有散列)它在我的cmd窗口中返回以下内容:城市、州城市、州城市、州,每对之间有一个\n…那么这是否意味着这是一个数组?很抱歉,我只是不明白。我以为我已经通过了混乱的信息并拉出城市、州来度过了难关…我所需要的只是计数,但这个似乎比我想象的要困难得多。我可以通过以下方式创建它:[at]places=($city,$state)?啊,好的,我刚刚看到了你更新的问题。如果你在单独的变量中有城市和州,那么你可以构建一个包含它们的字符串,并使用上面类似的代码。我将更新我的答案……我想我应该使用
$count{$city}{$state}++
而不是
$count{$city,$state}++
。问题中没有提到这一点,但我打赌在某个时候他会想按州报告城市。@DaveCross我本来想提的,但已经很长了。然后我忘了。:D
$line =~ /(?:\>)((\w+.*))(?:\<)/;
foreach $count (keys %counts){
$counts = {$city, $state} {$count}++;
print $counts;
}
my %counts;    # declare outside the loop
while ( my $line = <$fh> ) {
    chomp $line;
    if ( $varc == 3 ) {
        $line =~ /(?:\>)(\w+.*)(?:\<)/;
        $city = $1;
    }
    if ( $vars == 5 ) {
        $line =~ /(?:\>)((\w+.*))(?:\<)/;
        $state = $1;

        print "$city, $state\n";

        $count{"$city, $state"}++;    # increment when seen
    }
}
my %counts;    # declare outside the loop
while ( my $line = <$fh> ) {
    chomp $line;
    if ( $varc == 3 ) {
        $line =~ /(?:\>)(\w+.*)(?:\<)/;
        $city = $1;
    }
    if ( $vars == 5 ) {
        $line =~ /(?:\>)((\w+.*))(?:\<)/;
        $state = $1;

        $count{"$city, $state"}++;    # increment when seen
    }
}

# iterate again to print final counts
foreach my $item ( sort keys %counts ) {
    print "$item $counts{$item}\n";
}