R: Как сделать переключение оператора падения - PullRequest
0 голосов
/ 05 мая 2018

Во многих языках есть инструкция под названием break, которая говорит интерпретатору выйти из коммутатора после текущей инструкции. Если вы его опустите, переключатель провалится после обработки текущего случая:

switch (current_step)
{
  case 1: 
    print("Processing the first step...");
    # [...]
  case 2: 
    print("Processing the second step...");
    # [...]
  case 3: 
    print("Processing the third step...");
    # [...]
    break;
  case 4: 
    print("All steps have already been processed!");
    break;
}

Такой шаблон проектирования может быть полезен, если вы хотите пройти через серию переходных условий.


Я понимаю, что это может привести к ошибкам из-за непреднамеренного провала, если программист забывает вставить оператор разрыва, но несколько языков по умолчанию ломаются и включают ключевое слово провала (например, continue в Perl).

По замыслу переключатель R по умолчанию также отключается в конце каждого случая:

switch(current_step, 
  {
    print("Processing the first step...")
  },
  {
    print("Processing the second step...")
  },
  {
    print("Processing the third step...")
  },
  {
    print("All steps have already been processed!")
  }
)

В приведенном выше коде, если current_step установлен в 1, выход будет только "Processing the first step...".


Есть ли в R способ заставить корпус переключателя пробиться через следующий корпус?

1 Ответ

0 голосов
/ 06 мая 2018

Похоже, что такое поведение невозможно с switch(). Как предлагается в комментариях, лучшим вариантом было реализовать мою собственную версию.


Таким образом, я добавил обновление для моего optional пакета, чтобы реализовать эту функцию ( CRAN ).

В этом обновлении теперь вы можете использовать сквозной оператор в функции сопоставления с образцом match_with.

Шаблон дизайна в вопросе можно воспроизвести следующим образом:

library(optional)
a <- 1
match_with(a
    1, fallthrough(function() "Processing the first step..."),
    2, fallthrough(function() "Processing the second step..."),
    3, function() "Processing the third step...",
    4, function() "All steps have already been processed!"
)
## [1] "Processing the first step..." "Processing the second step..." "Processing the third step..."

Вы можете заметить, что match_with() очень похож на switch(), но имеет расширенные возможности. Например. шаблоны могут быть списками или функциональными последовательностями, а не простыми объектами для сравнения:

library("magrittr")
b <- 4
match_with(a,
  . %>% if (. %% 2 == 0)., 
  fallthrough( function() "This number is even" ),
  . %>% if ( sqrt(.) == round(sqrt(.)) ).,  
  function() "This number is a perfect square"
)
## [1] "This number is even" "This number is a perfect square"
...