r - R 中有类似 Rust 模式语法的东西吗?

标签 r rust switch-statement pattern-matching

我知道 R 中的 switch 语句,但我很好奇是否有一种方法可以将相同的操作/值分配给同一臂中的多个模式,类似于 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 的非字符串...这些整数返回 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 或 N 回收,而不是仅 N,但目前还不是这样。)

这有一个优点,那就是它是自然矢量化的。

switch 仅对长度为 1 友好。向量 x 的解决方法可能是

sapply(x, switch, '1'='a', '3'='z', '2'='y', '4'='f')

(或者更好的是,vapply强制返回class)。

关于r - R 中有类似 Rust 模式语法的东西吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66410401/

相关文章:

r - 如何有效识别重复的有序对

arrays - 为什么我不能在 Rust 中将元素写入数组中移动的位置,但我可以在元组中做到这一点

switch-statement - 发送电子邮件 - MFMailComposeResult

r - 在 list.dirs 中包含模式

r - knitr 中的特殊字符(cairoDevice 不起作用)

rust - 如何为特征实现指定引用生命周期?

c - 程序停止处理 switch 语句 C 语言

c - c中的switch case,默认在case之前

r - 从大型数据集中生成重复数据的子集

rust - 如何在转换为 trait 对象时使用 Rc::clone?