Я разбираю строку с использованием цикла while и вставляю разделенные элементы во временную таблицу. Это сложно, но я копирую и вставляю код, а затем изменяю имя таблицы для удобочитаемости. Ниже приведен пример для разбора списка идентификаторов пользователей с разделителями-запятыми в таблице temp:
CREATE PROCEDURE spParse
(_UserList MEDIUMTEXT)
BEGIN
DECLARE _Pos INT;
DECLARE _Start INT;
DECLARE _Item INT;
DECLARE _Length INT;
CREATE TEMPORARY TABLE IF NOT EXISTS TempUserList
(
UserID INT
);
SET _Length = LENGTH(_UserList);
SET _Pos = 1;
SET _Start = 1;
divide_loop:LOOP
IF _Pos > _Length Then
LEAVE divide_loop;
End If;
IF SUBSTRING(_UserList,_Pos,1) = ',' Then
IF _Pos - _Start > 0 Then
IF IsNumeric(SUBSTRING(_UserList,_Start,_Pos-_Start)) Then
SET _Item = CONVERT(SUBSTRING(_UserList,_Start,_Pos-_Start),Signed);
INSERT INTO TempUserList (UserID)
VALUES (_Item);
End If;
End If;
SET _Start = _Pos + 1;
End If;
SET _Pos = _Pos + 1;
END LOOP divide_loop;
IF _Start <= _Length Then
If IsNumeric(SUBSTRING(_UserList,_Start,_Length - _Start + 1)) Then
SET _Item = CONVERT(SUBSTRING(_UserList,_Start,_Length - _Start + 1),Signed);
INSERT INTO TempUserList (UserID)
VALUES (_Item);
End If;
End If;
SELECT UserID FROM TempUserList;
DROP TABLE TempUserList;
END
Предполагая, что если a
является логическим NA, тогда оно все равно должно вернуть 0, тогда попробуйте это (или замените вторую строку тела на a * b
, если логический NA для a
) должен вернуть НС).
В любом случае, главное, что следующий стиль stopifnot
можно использовать для проверки аргументов.
func2 <- function(a, b) {
stopifnot(is.logical(a), is.numeric(b))
isTRUE(a) * b
}
func2(TRUE, 3)
## [1] 3
func2(9, 2)
## Error in func2(9, 2) : is.logical(a) is not TRUE
Вместо stopifnot
используйте if (...) stop(...)
, по одному такому утверждению на аргумент, если вам нужны пользовательские сообщения об ошибках.
Обратите внимание, что можно использовать S3 для отправки в метод на основе первого аргумента или S4 для отправки в данную сигнатуру. Если метод для такой подписи не существует, будет вызвана ошибка.
Вот пример S4:
setMethod("func3", c("logical", "numeric"), function(a, b) isTRUE(a) * b)
func4(TRUE, 3)
## [1] 3
func4(2, 1)
## Error in UseMethod("func3") :
## no applicable method for 'func4' applied to an object of class "c('double', 'numeric')"
Вот пример S3:
# check 1st arg using S3 dispatch and 2nd arg using stopifnot
func3 <- function(a, b) UseMethod("func4")
func3.logical <- function(a, b) {
stopifnot(is.numeric(b))
isTRUE(a) * b
}
func3(TRUE, 3)
## [1] 3
func3(3, 8)
## Error in UseMethod("func3") :
## no applicable method for 'func3' applied to an object of class "c('double', 'numeric')"
В CRAN есть пакет с именем checkmate для проверки аргументов, которая используется довольно многими другими пакетами (заменяя ныне несуществующий пакет ArgumentCheck ). Другой пакет для проверки типа аргументов - TypeInfo на Bioconductor.
Существует пакет под названием rtype для строгой проверки типов.
Также есть пакеты assertive.types , assertive , assertr , assertable и assertthat для типа утверждения.
Также отметим, что в отношении кода в вопросе, что класс S3 является вектором и может иметь более одного элемента, используйте is.someclass
(если такая функция существует для someclass
) или inherits(X, "someclass")
, где [1112 ] интересующий класс, а не class(X) == "someclass"
для проверки классов S3.