R 中是否有类似于 Rust 模式语法的东西?
Is there something similar to Rust pattern syntax in R?
我知道 R 中的 switch 语句,但我很好奇是否有一种方法可以将相同的 action/value 分配给同一臂中的多个模式,类似于 Rust 中的方式:
let x = 1;
match x {
1 | 2 => println!("one or two"),
3 => println!("three"),
_ => println!("anything"),
}
我不需要为 1 和 2 写两个单独的案例,我可以用'|'将它们组合成一个。如果我可以在没有匹配之前的模式的情况下定义默认大小写(“_”),那也会很有帮助。
没有赋值的先前值会继续执行,直到找到赋值为止。
switch(
as.character(x),
"1"=,
"2"="one or two",
"3"="three",
"anything"
)
我使用 as.character(x)
而不是 x
因为 EXPR
(第一个参数)可能被解释为位置而不是相等。来自 ?switch
:
If the value of 'EXPR' is not a character string it is coerced to
integer. Note that this also happens for 'factor's, with a
warning, as typically the character level is meant. If the
integer is between 1 and 'nargs()-1' then the corresponding
element of '...' is evaluated and the result returned: thus if the
first argument is '3' then the fourth argument is evaluated and
returned.
所以如果 x
是一个介于 1 和其他参数数量之间的整数,那么它被解释为一个位置指示符,如
switch(3, 'a','z','y','f')
# [1] "y"
这意味着命名参数实际上被忽略了,就像这个非常令人困惑的例子
switch(3, '1'='a','3'='z','2'='y','4'='f')
# [1] "y"
请注意,帮助不引用大于 nargs()-1
的非字符串...那些整数 return null:
(switch(9, '1'='a','3'='z','2'='y','4'='f'))
# NULL
因为它是您要匹配的整数的值,您需要混淆地转换为字符串:
switch(as.character(3), '1'='a','3'='z','2'='y','4'='f')
# [1] "z"
或者,
dplyr::case_when(
x %in% 1:2 ~ "one or two",
x == 3 ~ "three",
TRUE ~ "anything"
)
# [1] "one or two"
或
data.table::fcase(
x %in% 1:2 , "one or two",
x == 3 , "three",
rep(TRUE, length(x)), "anything"
)
(需要 rep(TRUE,length(x))
是因为 fcase
要求所有参数的长度完全相同,即它不允许像许多 R 函数所允许的那样进行回收。我个人更希望它们允许1 or N
回收而不是 only N
,但目前不是这样。)
这有一个优势,它是自然向量化的。
switch
仅对长度为 1 友好。矢量 x
的解决方法可能是
sapply(x, switch, '1'='a', '3'='z', '2'='y', '4'='f')
(或者,更好的是,vapply
强制执行 return class
)。
我知道 R 中的 switch 语句,但我很好奇是否有一种方法可以将相同的 action/value 分配给同一臂中的多个模式,类似于 Rust 中的方式:
let x = 1;
match x {
1 | 2 => println!("one or two"),
3 => println!("three"),
_ => println!("anything"),
}
我不需要为 1 和 2 写两个单独的案例,我可以用'|'将它们组合成一个。如果我可以在没有匹配之前的模式的情况下定义默认大小写(“_”),那也会很有帮助。
没有赋值的先前值会继续执行,直到找到赋值为止。
switch(
as.character(x),
"1"=,
"2"="one or two",
"3"="three",
"anything"
)
我使用 as.character(x)
而不是 x
因为 EXPR
(第一个参数)可能被解释为位置而不是相等。来自 ?switch
:
If the value of 'EXPR' is not a character string it is coerced to
integer. Note that this also happens for 'factor's, with a
warning, as typically the character level is meant. If the
integer is between 1 and 'nargs()-1' then the corresponding
element of '...' is evaluated and the result returned: thus if the
first argument is '3' then the fourth argument is evaluated and
returned.
所以如果 x
是一个介于 1 和其他参数数量之间的整数,那么它被解释为一个位置指示符,如
switch(3, 'a','z','y','f')
# [1] "y"
这意味着命名参数实际上被忽略了,就像这个非常令人困惑的例子
switch(3, '1'='a','3'='z','2'='y','4'='f')
# [1] "y"
请注意,帮助不引用大于 nargs()-1
的非字符串...那些整数 return null:
(switch(9, '1'='a','3'='z','2'='y','4'='f'))
# NULL
因为它是您要匹配的整数的值,您需要混淆地转换为字符串:
switch(as.character(3), '1'='a','3'='z','2'='y','4'='f')
# [1] "z"
或者,
dplyr::case_when(
x %in% 1:2 ~ "one or two",
x == 3 ~ "three",
TRUE ~ "anything"
)
# [1] "one or two"
或
data.table::fcase(
x %in% 1:2 , "one or two",
x == 3 , "three",
rep(TRUE, length(x)), "anything"
)
(需要 rep(TRUE,length(x))
是因为 fcase
要求所有参数的长度完全相同,即它不允许像许多 R 函数所允许的那样进行回收。我个人更希望它们允许1 or N
回收而不是 only N
,但目前不是这样。)
这有一个优势,它是自然向量化的。
switch
仅对长度为 1 友好。矢量 x
的解决方法可能是
sapply(x, switch, '1'='a', '3'='z', '2'='y', '4'='f')
(或者,更好的是,vapply
强制执行 return class
)。