我怎样才能惯用地忽略未定义的数组元素(或者首先避免将它们分配给数组)?

Chr*_*oms 9 perl6 raku

如果为数组分配未定义的值,它将包含该未定义的值,如果您不想迭代未定义的值,则会使用循环复杂化:

my @bar = 1, 2, Any;

for @bar -> $baz {
    put $baz;
}
Run Code Online (Sandbox Code Playgroud)

这给出了以下输出,包括对未定义值的警告:

1
2
Use of uninitialized value $baz of type Any in string context.
Methods .^name, .perl, .gist, or .say can be used to stringify it to something meaningful.
  in block  at for.p6 line 4
Run Code Online (Sandbox Code Playgroud)

我知道我可以通过多种方式明确地处理这个问题,例如:

for @bar -> $baz {
    next unless $baz; # Skip this iteration
    put $baz;
}

for @bar.grep: *.defined {    # Just iterate over the defined values
    put $baz;
}

# Reassign @bar to only contain defined values
@bar.=grep(*.defined);
for @bar -> $baz {
    put $baz;
}
Run Code Online (Sandbox Code Playgroud)

但是,是不是有更惯用的方法来避免@foo接收未定义的值或避免迭代未定义的值?


目前,在分配数组时,我将使用以下defined-flat函数来避免这些情况:

multi defined-flat (@array) {
    return @array.grep(*.defined).flat;
}

# Return single defined element (or empty list for single undefined value)
multi defined-flat ($element) {
    return $element // ();
}
Run Code Online (Sandbox Code Playgroud)

Bra*_*ert 6

你可以用 duckmap

my @bar = 1, 2, Any;

@bar.duckmap: -> Mu:D $baz {
    put $baz;
}
Run Code Online (Sandbox Code Playgroud)
duckmap -> Mu:D $baz {
    put $baz;
}, @bar;
Run Code Online (Sandbox Code Playgroud)
# the “:” makes this a method call
duckmap @bar: -> Mu:D $baz {
    put $baz;
}
Run Code Online (Sandbox Code Playgroud)


dwa*_*ing 6

有时也很方便的是with语句,它既可以定义,也可以测试定义:

my @bar = 1, 2, Any;

for @bar -> $baz {
    put $_ with $baz
}
Run Code Online (Sandbox Code Playgroud)

要么:

my @bar = 1, 2, Any;

for @bar {
    with $_ -> $baz {
        put $baz;
    }
}
Run Code Online (Sandbox Code Playgroud)