1) продублировано Используя тестовый ввод, показанный в первой строке, переберите индекс и добавьте условие, используя duplicated
. Это позволяет избежать использования флага, что делает его менее подверженным ошибкам.
id_list <- c("a", "snake", "b", "snake") # test input
dup <- duplicated(id_list)
for(i in seq_along(id_list)) {
if (id_list[i] == "snake" && (!dup)[i]) print("snake")
print(i)
}
, дающий:
[1] 1
[1] "snake"
[1] 2
[1] 3
[1] 4
2) match Другой подход, позволяющий определить, какая итерация представляет первый экземпляр snake
и использовать его в условии.
ix <- match("snake", id_list, nomatch = 0)
for(i in seq_along(id_list)) {
if (i == ix) print("snake")
print(i)
}
, дающий:
[1] 1
[1] "snake"
[1] 2
[1] 3
[1] 4
3) один раз
Другой подход заключается в создании функции once
, которая возвращает значение TRUE первым время это бежит и ЛОЖЬ в противном случае. При этом используется изменяемая переменная x
(аналогично флагу), но по крайней мере она инкапсулирована. Функция genOnce
выводит функцию fre sh once
.
Важно использовать && в условии, чтобы гарантировать, что правая часть && выполняется, только если левая сторона равна TRUE , & не имеет этого свойства короткого замыкания.
genOnce <- function(x = 0) function() (x <<- x + 1) == 1
once <- genOnce()
for(id in id_list) {
if (id == "snake" && once()) print("***")
print(id)
}
давая:
[1] "a"
[1] "***"
[1] "snake"
[1] "b"
[1] "snake"