微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

perl6 – 创建任意分组的子列表

我正在尝试根据每个字符串的第一部分(即,如果有选项卡,则在第一个选项卡之前的部分或如果没有选项卡的整个字符串)对字符串列表中的多个项目进行分组.

这有效:

use Test;

my @lines    = "A\tFoo","A\tBar","B","A\tBaz","B"
             ;

my @expected = ["A\tFoo","A\tBar"],["B","B"],["A\tBaz"],["B"]
             ;

my @result = group-lines(@lines);

is @result,@expected,"Grouped correctly";

sub group-lines (@records) {
    my @groups;
    my @current-records;

    my $last-type;
    for @records -> $record {

        my $type = $record.split("\t")[0];

        once { $last-type = $type }

        if $type ne $last-type {
            @groups.push: [@current-records];
            @current-records = ();
        }
        @current-records.push: $record;

        LAST { @groups.push: [@current-records] }
    }

    return @groups;
}

但它似乎很冗长.在Perl 6中没有更短的方法吗?请注意,我只想将类似于原始列表的连续成员的项目分组.

(更新)组内的顺序很重要.

UPDATE

这是一个更加数字化的例子.它根据后续数字与第一个数字的可分性对数字进行分组.

#!/bin/env perl6
use Test;

my @numbers = 2,4,6,3,9,12,14;

my @expected = [2,6],[3,12],[14];

my @result = group-nums(@numbers);

is @result,"Grouped correctly";

sub group-nums (@numbers) {
    my @groups;
    my @current-group;

    my $denominator = @numbers[0];

    for @numbers -> $num {

        if $num % $denominator {
            @groups.push: [@current-group];
            @current-group = ();
        }
        @current-group.push: $num;

    }
    @groups.push: [@current-group];

    return @groups;
}

解决方法

这是一个功能灵感的解决方案,虽然可能有点复杂:

use Test;

my @lines    = "A\tFoo",["B"]
             ;

my @eq = @lines.map(*.split("\t")[0]).rotor(2 => -1).map({ [eq] .list});
my @result = [@lines[0],],;
for @lines[1..*] Z @eq -> ($line,$eq) {
    @result.push([]) unless $eq;
    @result[*-1].push: $line;
}

plan 1;
is-deeply @result,@expected;

这个想法是@eq包含每个位置(第一个除外)如果前一个元素与当前元素具有相同的前缀,则为真.

但是我们并没有假装Lisp是唯一真神,而car和cdr是她的先知,我们可以简单地通过使用数组索引在我们需要时访问前一个元素来内联该决定:

my @result;
for @lines.kv ->  $idx,$elem {
    @result.push([]) if $idx == 0 || $elem.split("\t")[0] ne @lines[$idx-1].split("\t")[0];
    @result[*-1].push: $elem;
}

plan 1;
is-deeply @result,@expected;

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐