首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何通过AT-POS为不同的类实现2d下标?

如何通过AT-POS为不同的类实现2d下标?
EN

Stack Overflow用户
提问于 2022-02-03 18:10:12
回答 2查看 91关注 0票数 8

下面是一个MRE (展示了两次尝试,为了帮助您进行调试),以尝试在一个包含系列列的DataFrame上使用across获得2d订阅。

代码语言:javascript
运行
复制
class Series does Positional {
    has Real @.data = [0.1,0.2,0.3];

    method AT-POS( $p ) { 
        @!data[$p]
    }   
}

class DataFrame does Positional {
    has Series @.series;

#`[ ATTEMPT #1
    method AT-POS( $p, $q? ) { 
        given $q {
            when Int {                  #say 'Int';
                @!series[$p][$q]
            }   
            when Whatever {             #say '*';
                @!series[$p].data 
            }   
            default {                   #say 'default';
                @!series[$p] 
            }   

        }   
    }   
#]
    # ATTEMPT #2
    method AT-POS(|c) is raw { #`[dd c;] @!series.AT-POS(|c) }
}

my $df = DataFrame.new( series => [Series.new xx 3] );

say $df[1].data;            #[0.1 0.2 0.3]
say $df[1][2];              #0.3
say $df[0,1];               #(Series.new(data => $[0.1, 0.2, 0.3]) Series.new(data => $[0.1, 0.2, 0.3]))
say $df[1;2];               #0.3
say $df[1;*];               #got (0.1) ... expected [0.1 0.2 0.3]
say $df[*;1];               #got (0.2) ... wanted [0.2 0.2 0.2]

我已经对SO进行了研究,发现了这里这里这里三个相关问题。我的代码中的第二次尝试试图将@lizmats的答案应用于第三个。令人鼓舞的是,在我的MRE中,两次尝试都有相同的行为。但我不能锻炼

  • 为什么没有输入when Whatever {}选项(尝试#1)
  • |c正在做什么--尽管我可以看到它在单个下标情况下工作(尝试#2)

我在multi postcircumfix:<[ ]>( DataFrame:D $df, @slicer where Range|List ) is export {}上做了一些实验,但这似乎使事情变得过于复杂。

==================

来自“乔纳森建筑”的回答非常好,来自“莉兹马特”的原文--谢谢!下面是最后的工作代码:

代码语言:javascript
运行
复制
class Series does Positional {
    has Real @.data = [0.1,0.2,0.3];

    method elems {
        @!data.elems
    }   

    method AT-POS( |p ) is raw {
        @!data.AT-POS( |p )
    }   
}

class DataFrame does Positional {
    has Series @.series;

    method elems { 
        @!series.elems
    }   

    method AT-POS( |p ) is raw { 
        @!series.AT-POS( |p )
    }   
}

my $df = DataFrame.new( series => Series.new xx 3 );

say $df[1].data;            #[0.1 0.2 0.3]
say $df[1][2];              #0.3
say $df[0,1];               #(Series.new(data => $[0.1, 0.2, 0.3]) Series.new(data => $[0.1, 0.2, 0.3]))
say $df[1;2];               #0.3
say $df[1;*];               #(0.1 0.2 0.3)
say $df[*;1];               #(0.2 0.2 0.2)
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-02-03 18:24:51

AT-POS方法只被传递过整数数组索引。

处理切片的逻辑(使用*、ranges、其他可迭代、zen切片)位于数组索引操作符中,它被实现为用于一维索引的多分派子例程postcircumfix:<[ ]>和用于多维索引的postcircumfix:<[; ]>。这样做的想法是,想要充当数组类的类不必担心重新实现所有的切片行为,而且切片行为将在不同的用户定义类型上保持一致。

要实现切片工作,必须实现elemsAT-POS。增加:

代码语言:javascript
运行
复制
method elems() { @!data.elems }

Series,并且:

代码语言:javascript
运行
复制
method elems() { @!series.elems }

DataFrame中给出了您正在寻找的结果。

如果一个人真的想要不同的切片语义,或者一个比标准的实现更高效的实现,我们还可以为索引操作符添加multi候选项(记住标记它们is export)。

票数 8
EN

Stack Overflow用户

发布于 2022-02-09 23:21:09

这个答案只是简单地阐述了@raiph在一个评论中的观点:

您可以使用句柄简化代码。

事实上,您可以--以至于我认为值得在没有注释格式限制的代码块中展示它是什么样子。

使用handles,您可以将这两个类中的每个类从9个非空白行简化为3:

代码语言:javascript
运行
复制
class Series does Positional {
    has Real @.data handles <elems AT-POS> = [0.1,0.2,0.3];
}

class DataFrame does Positional {
    has Series @.series handles <elems AT-POS>;
}

(或者,您甚至可以让每个类放在一行上,如果您按照我想要的方式设置它们的格式的话。)

此代码从问题中的代码向say语句生成所有相同的结果。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70976231

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档