【问题标题】:Perl - how do I get the previous key in a hash?Perl - 如何获取哈希中的前一个键?
【发布时间】:2012-09-01 05:31:42
【问题描述】:

我有一个散列,其中填充了未知数量的字符串键。每个键的值都是零开始。

我想遍历这个散列,并且对于除第一个元素之外的每个元素,使其值等于我拥有的另一个散列中的等价物加上此散列中的前一个值。所以在数学上是这样的:

hash1:a = hash2:a;
hash1:b = hash2:b + hash1:a;
hash1:c = hash2:c + hash1:b;
hash1:d = hash2:d + hash1:c;
hash1:e = hash2:e + hash1:d;
...

我什至不确定我知道如何做第一个,因为我不知道值或键是什么。我打算先对它进行排序,但由于键可以是列表中的任何键,我无法准确指定首先是什么。我不知道如何根据键引用以前的值。这可能吗?

(恐怕我没有任何代码可以显示,我试过但我发现这是非常错误的哈哈)

【问题讨论】:

    标签: perl hash loops key-value


    【解决方案1】:

    哈希本身是无序的,所以他们不知道“前一个”键。您需要使用 keys 函数提取键,对它们进行排序(如您所说),然后参考键列表的前一个元素以找出您选择的顺序中的前一个键是什么。

    一旦您有了之前的键,您就可以使用通常的 $hash{$key} 语法从哈希中访问该值。

    然后技巧变成访问列表中的前一个键,这可能需要按索引迭代列表,因为foreach 循环不会让您知道您当前在列表中的哪个位置。类似的东西

    for (my $i = 0; $i <= $#keys; ++$i) {
        if ($i == 0) { ... } # first key
        else { ... } # all other keys
    }
    

    可能合适。

    【讨论】:

    • 大多数 Perl 程序员更喜欢 for my $i ( 0 .. $#keys ) 而不是 C 风格的循环。 (或foreach...,但forforeach 在Perl 中完全等价,我更喜欢较短的拼写。)
    • 关于范围版本的好点,我倾向于忘记这一点,除非我出于某种原因在 Perl 6 中编程。我也更喜欢for 的较短拼写,因为foreach 只是一个同义词。我已经到了让我非常恼火的地步,在 C# 中情况并非如此,我必须继续在任何地方写 foreach
    【解决方案2】:

    这基本上是所有哈希值的累积和

    a’ = (0) + a
    b’ = (0  + a) + b
    c’ = (0  + a  + b) + c
    d’ = 0 + ...
    

    遍历散列,存储总和并始终将当前值相加(或将总和添加到当前值,没关系,加法是可交换的)应该可以获得所需的结果。 请注意,您必须先对键进行排序,因为哈希在定义上是无序的。

    $sum = 0;
    foreach my $k (sort keys %hash) {
      $hash{$k} += $sum;
    }
    

    生成的哈希也不会被排序,所以你有两个选择:

    • 每次使用散列(对其进行迭代)时,都必须对已排序的键进行迭代,然后在该键位置访问散列。只需使用我上面给出的循环并将其主体换成你想要的任何东西。
    • 将总和存储在列表/数组中。这些数据结构不会更改其值的顺序(但您不会有键值对;只有值)。

    【讨论】:

    • 这行不通。当您更改哈希时,键的顺序可能会更改。下一个订单可能会有所不同,您将不知道为什么会有任何价值。
    • @briandfoy:没错,但我们遍历的是排序后的键列表,而不是原始哈希。
    • @briandfoy:哦,我现在明白你在说什么了……好吧,要么在输出散列/迭代散列时始终按键排序,要么将结果存储在散列中,而是存储在而是简单的列表。
    猜你喜欢
    • 2013-02-12
    • 1970-01-01
    • 2021-12-30
    • 1970-01-01
    • 1970-01-01
    • 2014-10-17
    • 2016-06-10
    • 2020-11-24
    • 2010-11-02
    相关资源
    最近更新 更多