当前位置: 首页 > 知识库问答 >
问题:

Raku:多维哈希值的访问问题

谯翔
2023-03-14

我在访问二维哈希值时遇到问题。从我在网上可以看出,它应该是这样的:%myHash{"key1"}{"key2"}#返回值

然而,我得到了一个错误:“类型数组不支持关联索引。”

这是一个最小的可复制示例。

my %hash = key1-dim1 => key1-dim2 => 42, key2-dim1 => [42, 42];
say %hash{'key1-dim1'}{'key1-dim2'}; # 42
say %hash{'key2-dim1'}{'foo bar'};   # Type Array does not support associative indexing.

下面是另一个可复制的示例,但时间更长:

my @tracks = 'Foo Bar', 'Foo Baz';
my %count;
for @tracks -> $title {
        $_ = $title;
        my @words = split(/\s/, $_);
        if (@words.elems > 1) {
            my $i = 0;
            while (@words.elems - $i > 1) { 
                my %wordHash = ();
                %wordHash.push: (@words[$i + 1] => 1);
                %counts.push: (@words[$i] => %wordHash);
                say %counts{@words[$i]}{@words[$i+1]}; #===============CRASHES HERE================
                say %counts.kv;
                $i = $i + 1;
            }
        }
    }

在我上面的代码中,访问二维哈希值的问题行将在for循环的第一次迭代中工作一次。然而,它总是在第二次通过时崩溃。我尝试过用静态键值替换大括号中的数组引用,以防这些键值有什么奇怪的地方,但这并不影响结果。我似乎无法通过在线搜索找到到底出了什么问题。

我对raku很陌生,所以如果这是显而易见的事情,我道歉。

共有3个答案

居琛
2023-03-14

嗯,这一次很有趣,也很令人惊讶。如果您按照另一个问题进行操作,则不会出错,但是,以下是您的程序的修改版本:

my @tracks = ['love is love','love is in the air', 'love love love'];
my %counts;
for @tracks -> $title {
    $_ = $title;
    my @words = split(/\s/, $_);
    if (@words.elems > 1) {
        my $i = 0;
        while (@words.elems - $i > 1) {
            my %wordHash = ();
            %wordHash{@words[$i + 1]} = 1;
            %counts{@words[$i]} = %wordHash;
            say %counts{@words[$i]}{@words[$i+1]}; # The buck stops here
            say %counts.kv;
            $i = $i + 1;
        }
    }
}

请检查之前发生故障的线路。你能看出区别吗?你用i作为循环变量是一件(不)幸运的事<代码>i是Raku中的一个复数。所以它崩溃了,因为它不能使用复数来索引数组。你只是丢掉了美元。

您可以在Raku中使用无符号变量,只要它们不是i、e或任何其他已定义的常量。

正如卢卡斯·瓦勒(LukasValle)所说,我还做了一些修改,以更好地反映这样一个事实,即您正在构建一个散列,而不是一个对数组。

华锦程
2023-03-14

首先让我解释一下最简单的例子:

my %hash = key1-dim1 => key1-dim2 => 42,
           key2-dim1 => [42, 42];

say %hash{'key1-dim1'}{'key1-dim2'}; # 42
say %hash{'key2-dim1'}{'key2-dim2'}; # Type Array does not support associative indexing.

问题是与key2-dim1关联的值本身不是哈希,而是ArrayArrays(和所有其他Posiationals)仅支持按位置-整数进行索引。它们不支持按关联-按字符串或对象键进行索引。

希望这能解释这一点。另请参阅使用标记加上“类型数组不支持关联索引”搜索SO。

您的较长示例在这一行中抛出了一个错误—不是立即抛出,而是最终抛出:

say %counts{...}{...}; # Type Array does not support associative indexing.

哈希计数百分比由前一行构成:

%counts.push: ...

为哈希提取文档。推送:

  • 如果哈希中已经存在键...旧值和新值都放置在Array

示例:

my %h  = a => 1;
%h.push: (a => 1);              # a => [1,1]

现在考虑以下代码将与文档中的示例具有相同的效果:

my %h;
say %h.push: (a => 1);          # {a => 1}
say %h.push: (a => 1);          # {a => [1,1]}

请注意的第一个。推送a=

代码中也发生了类似的事情。

在您的代码中,您将值%wordHash推送到%count哈希的@word[$i]键中。

第一次执行此操作时,与%count中的@word[$i]键关联的结果值只是您推送的值-%wordHash。这就像上面1的第一次推送一样,导致与a键关联的值,从推送中,为1

因为wordHash本身就是一个哈希,所以可以关联索引到其中。所以<代码>%计数{…}{...} 工作。

但是第二次将值推送到相同的%count键时(即当键是%count{@word[$i]}时,@word[$i]设置为已由%count持有的单词/字符串/键),那么与该键关联的值最终不会与%wordHash关联,而是与[%wordHash,%wordHash]关联。

如果你输入的曲目标题都是以同一个单词开头的,那么你的代码中显然会出现这样的第二次。(我认为即使复制不是第一个词,而是后面的词,情况也是如此。但我对你的代码太困惑了,无法确定确切的断开组合是什么。而且现在我想理解它已经太晚了,尤其是考虑到它似乎并不重要。)

因此,当您的代码然后计算%count{@word[$i]}{@word[$i 1]}时,它与[%wordHash,%wordHash]{...}相同。这没有意义,所以您会看到错误。

希望上述内容有所帮助。

但我必须说,我对您的代码感到困惑,也对您实际想要实现的目标感到好奇。

我知道你只是在学习Raku,你从中获得的可能已经足够了,但Raku有一系列很好的高级散列数据类型和功能,如果你描述你的目标,我们可能能够帮助你消除你和我们迄今为止一直在处理的Raku皱纹。

无论如何,欢迎来到SO和Raku.:)

茅鸿宝
2023-03-14

在将第二个带有推送的元素添加到Hash的同一部分后,elment现在是一个数组。最好在崩溃前打印Hash来查看这一点:

 say "counts: " ~  %counts.raku;
 #first time: counts: {:aaa(${:aaa(1)})}
 #second time: counts: {:aaa($[{:aaa(1)}, {:aaa(1)}])}

方括号表示数组。

也许BagHash已经为您做了一些工作。另请参阅raku集无边界

my @tracks = 'aa1 aa2 aa2 aa3', 'bb1 bb2', 'cc1';
for @tracks -> $title {
    my $n = BagHash.new: $title.words;
    $n.raku.say;
}

#("aa2"=>2,"aa1"=>1,"aa3"=>1).BagHash
#("bb1"=>1,"bb2"=>1).BagHash
#("cc1"=>1).BagHash

 类似资料:
  • 常见问题,Int Raku,如何合并,合并两个哈希? 说: 如何获取

  • 嗨,我想知道如果你有你要寻找的对象的Hashcode,是否可以直接访问HashSet的内容,有点像在HashMap中使用Hashcode作为键。 我想它可能会像这样工作: 谢谢 编辑:谢谢你的回答。好的,我知道我可能会稍微推动HashSet的契约,但是对于这个特定的项目,等式完全由hashcode决定,我确信每个hashcode/hashbucket只有一个对象。我非常不愿意使用HashMap的原

  • 在密码散列方面,我有点像n00b,所以对我来说很简单。基本上,我已经整理了一些代码,首先清理用户在注册时输入的字符串。一旦完成,就会生成随机盐。然后将密码附加到salt: 然后,我使用sha256对密码进行哈希处理,然后继续将用户插入数据库,这似乎都正常工作: 然后,当涉及到用户登录时,我再次清理用户输入的字符串,从数据库中获取salt并将其分配给变量,然后将密码附加到该变量,如下所示: 然后,像

  • 求求你帮帮我!我正在尝试使用pbkdf2-sha256算法哈希密码。Password=“user1”,salt=“ifo7kxyswe7fiu3bovnowg=”,hashIterations=“27500”。我知道结果。必须类似于“ZnxO94AYITK7T+OJ1PXPZTVEQ+G82LFWT6VNSTBHZPEUWZGMPRJJVKAUEXGH1IQPZWMX1SRVTUMLN/JCM8G

  • 问题内容: 我有两个用于计算SHA1的小片段。 一个非常快,但似乎不正确,另一个非常慢,但正确。 我认为转换为问题。 快速版本: 慢版本: 转换方式: 我希望有另一种可能使其运行,因为我需要性能。 问题答案: 我使用了JNI加载的高性能c ++实现。 有关更多详细信息,请发表评论。 编辑: JNI的要求是Android NDK。对于Windows,还需要cygwin或类似的东西。 如果您决定使用c

  • 在阅读std::unordered_map使用的std::hash示例时,我注意到,{}正在访问operator()函数。 http://en.cppreference.com/w/cpp/utility/hash 这里{}的用法代表什么?