如何检查某物是否是 qw 的元素?

How do I check if something is an elem of a qw?

根据文档 <a b c d e>qw|a b c d e| 是相似的,而且它们都生成列表,这意味着它们应该等同于 ('a', 'b', 'c', 'd', 'e').

为什么我不能这样做:'2' (elem) <1 2 3 4 5>

2 (elem) <1 2 3 4 5> 也不起作用,但 'a' (elem) <a b c d e> 起作用。

这是怎么回事?我不应该像其他任何东西一样检查号码是否存在吗?

如果你这样做:

<1 2 3 4 5>.raku.say

您会看到它创建了一个 IntStr 对象列表(这些对象可以是字符串或整数)。当我们把它们放在一个集合中时,我们得到一组 IntStr 对象。

问题是 (elem) 不使用智能匹配而是等价,Int 1String "1" 都不等价于 IntStr.new(1, "1")。他们都与 IntStr 进行智能匹配...

你可能想用first找针:

defined <1 2 3 4 5>.first( 2, :k )

first( $match, :k ) returns 第一个匹配项的索引和 Nil 如果没有匹配项。所以我们测试它是否被定义,如果是,我们的项目是否存在。

或者您可以使用 map.

将您的列表转换为字符串或整数
2 (elem) <1 2 3 4 5>.map( *.Int )

所以首先 <…> 实际上等同于:

q:w:v < … >

或更详细地说:

Q :single :words :val < … >

q:single 是指定单引号语义的方式。

'abc'
q 'abc'
Q :q 'abc'
Q :single 'abc'

:w:words 指定您希望字符串按空格分割。

Q :w     ' a b   c '    eqv    'a', 'b', 'c'
Q :words ' a b   c '    eqv    'a', 'b', 'c'

:v:val 指定您需要 val() 语义。
使用 val 会将表示数字的字符串转换为既是字符串又是数字的东西。

Q :v   '123'
Q :val '123'
val( '123' )
IntStr.new( 123, '123' )

请注意,您可以将 Qqqq 与单个字符选项结合使用

qw 'a b'   =:=   q:w 'a b'  =:=  q:words 'a b'
qb 'a\n'   =:=   q:b 'a\n'  =:=  q:backslash 'a\n'
qs 'a$_'   =:=   q:s 'a$_'  =:=  q:scalar 'a$_'

(可能是qv''不起作用的bug。)


无论如何 (elem) 和所有 Set/Bag/Mix 运算符处理特定的事情,而不是泛泛而谈。

1.0    (elem)   1,2,3; # False
1      (elem)   1,2,3; # True

因此,如果有任何不同,那些运营商会将它们视为不同的事物。

q:v '1'   (elem)   1; # False
q:v '1'   (elem)   IntStr.new(1,'1'); # True

<1>   (elem)   1; # False
<1>   (elem)   IntStr.new(1,'1'); # True

因为我们已经确定 <1> 不会 return 一个 Int,它 return 是一个 IntStr
IntStrInt 不完全相同,因此它不匹配 Int.


大概您希望数字事物仅是数字。

​< a b c 1 2 3 >.duckmap:  -> Numeric $_ { +$_ }

这会遍历列表,任何已经是数字的都会调用此函数。
该函数只做一件事,调用 prefix:« + » 对值调用 .Numeric

由于 IntStr 是一个 Int,它执行 Numeric,将根据这些值调用该函数。


您可能想知道为什么 <…> 使用 val 语义。

原因是无法知道您是否打算将其提供给需要 StrNumeric.

的函数
sub foo ( Str ){}
sub bar ( Int ){}

foo <1>;
bar <1>;

foo 1;   # Failure
bar '1'; # Failure

check if something is an element

(elem) 应用的唯一强制转换是使其右侧参数能够接受集合操作所需的最小值。它不在元素级别进行强制转换,而是对值进行严格比较。所以你必须应用你自己的显式强制转换,例如:

'2' (elem) qw<1 2 3>                   ; # True
'2' (elem) ~«<1 2 3>                   ; # True
'2' (elem)   <1 2 3>».Str              ; # True
'2' (elem)   <1 2 3> .map: *.Str       ; # True

2   (elem) +«<1 2 3>                   ; # True
2   (elem)   <1 2 3>».Int              ; # True
2   (elem)   <1 2 3> .map: *.Int       ; # True

'2' (elem)   <a 2> .duckmap: *.Int     ; # False
2   (elem)   <a 2> .duckmap: *.Int     ; # True
'a' (elem)   <a 2> .duckmap: *.Int     ; # False

'2' (elem)   <a 2> .duckmap: *.Str     ; # True
2   (elem)   <a 2> .duckmap: *.Str     ; # False
'a' (elem)   <a 2> .duckmap: *.Str     ; # True

«/» 将操作分发到树的叶子或列表参数。例如, 分配一个前缀 +,它将其参数强制转换为一个数字。

duckmap有点类似于«/»;一个主要区别是,如果操作不适用,它就会继续。也就是说,对每个元素尝试绑定(函数调用);如果类型签名匹配,则调用该函数并且其 return 值替换该元素,否则该元素将按原样保留在结果中。