在红宝石中,我可以做到
['Hi', 'Yo'].map(&:upcase)
但如果我想同时同时获得:upcase
和:downcase
该怎么办?
无论
['Hi', 'Yo'].map(&[:upcase,:downcase])
,也不
['Hi', 'Yo'].map([&:upcase,&:downcase])
的工作。 :(
答案 0 :(得分:4)
你在这里有什么:
['Hi', 'Yo'].map(&:upcase)
实际上是以下的简短版本:
['Hi', 'Yo'].map(&:upcase.to_proc)
以下是:
的变体['Hi', 'Yo'].map(&->(s) { s.send(:upcase) })
或换句话说:
['Hi', 'Yo'].map { |s| s.upcase }
对于这种情况,&:x
符号实际上是一种特殊情况的简写,仅适用于单数符号。您可以做的是定义一个大致如下的to_proc
方法:
class Array
def to_proc
->(i) { inject(i) { |v, m| v.send(m) } }
end
end
该方法必须返回一个Proc
对象,一个" lambda",这里使用Ruby -> (...) { ... }
表示法定义。
然后你可以这样称呼它:
['Hi', 'Yo'].map(&[:upcase, :downcase, :to_sym].to_proc)
# => [:hi, :yo]
答案 1 :(得分:1)
pooly <- function (object, method = "smallsample") {
call <- match.call()
if (!is.mira(object))
stop("The object must have class 'mira'")
m <- length(object$analyses)
fa <- getfit(object, 1)
if (m == 1) {
warning("Number of multiple imputations m=1. No pooling done.")
return(fa)
}
analyses <- getfit(object)
if (class(fa)[1] == "lme" && !requireNamespace("nlme", quietly = TRUE))
stop("Package 'nlme' needed fo this function to work. Please install it.",
call. = FALSE)
if ((class(fa)[1] == "mer" || class(fa)[1] == "lmerMod" ||
inherits(fa, "merMod")) && !requireNamespace("lme4",
quietly = TRUE))
stop("Package 'lme4' needed fo this function to work. Please install it.",
call. = FALSE)
mess <- try(coef(fa), silent = TRUE)
if (inherits(mess, "try-error"))
stop("Object has no coef() method.")
mess <- try(vcov(fa), silent = TRUE)
if (inherits(mess, "try-error"))
stop("Object has no vcov() method.")
if (class(fa)[1] == "mer" || class(fa)[1] == "lmerMod" ||
inherits(fa, "merMod")) {
k <- length(lme4::fixef(fa))
names <- names(lme4::fixef(fa))
}
else if (class(fa)[1] == "polr") {
k <- length(coef(fa)) + length(fa$zeta)
names <- c(names(coef(fa)), names(fa$zeta))
}
# added this ---------------------------------
else if (class(fa)[1] == "multinom") {
k <- length(coef(fa))
names <- rownames(vcov(fa))
}
# --------------------------------------------
else {
k <- length(coef(fa))
names <- names(coef(fa))
}
qhat <- matrix(NA, nrow = m, ncol = k, dimnames = list(seq_len(m),
names))
u <- array(NA, dim = c(m, k, k), dimnames = list(seq_len(m),
names, names))
for (i in seq_len(m)) {
fit <- analyses[[i]]
if (class(fit)[1] == "mer") {
qhat[i, ] <- lme4::fixef(fit)
ui <- as.matrix(vcov(fit))
if (ncol(ui) != ncol(qhat))
stop("Different number of parameters: class mer, fixef(fit): ",
ncol(qhat), ", as.matrix(vcov(fit)): ", ncol(ui))
u[i, , ] <- array(ui, dim = c(1, dim(ui)))
}
else if (class(fit)[1] == "lmerMod" || inherits(fa, "merMod")) {
qhat[i, ] <- lme4::fixef(fit)
ui <- vcov(fit)
if (ncol(ui) != ncol(qhat))
stop("Different number of parameters: class lmerMod, fixed(fit): ",
ncol(qhat), ", vcov(fit): ", ncol(ui))
u[i, , ] <- array(ui, dim = c(1, dim(ui)))
}
else if (class(fit)[1] == "lme") {
qhat[i, ] <- fit$coefficients$fixed
ui <- vcov(fit)
if (ncol(ui) != ncol(qhat))
stop("Different number of parameters: class lme, fit$coefficients$fixef: ",
ncol(qhat), ", vcov(fit): ", ncol(ui))
u[i, , ] <- array(ui, dim = c(1, dim(ui)))
}
else if (class(fit)[1] == "polr") {
qhat[i, ] <- c(coef(fit), fit$zeta)
ui <- vcov(fit)
if (ncol(ui) != ncol(qhat))
stop("Different number of parameters: class polr, c(coef(fit, fit$zeta): ",
ncol(qhat), ", vcov(fit): ", ncol(ui))
u[i, , ] <- array(ui, dim = c(1, dim(ui)))
}
else if (class(fit)[1] == "survreg") {
qhat[i, ] <- coef(fit)
ui <- vcov(fit)
parnames <- dimnames(ui)[[1]]
select <- !(parnames %in% "Log(scale)")
ui <- ui[select, select]
if (ncol(ui) != ncol(qhat))
stop("Different number of parameters: class survreg, coef(fit): ",
ncol(qhat), ", vcov(fit): ", ncol(ui))
u[i, , ] <- array(ui, dim = c(1, dim(ui)))
}
# added this block -------------------------------------
else if (class(fit)[1] == "multinom") {
qhat[i, ] <- c(t(coef(fit))) # transpose to get same order as standard errors
ui <- vcov(fit)
if (ncol(ui) != ncol(qhat))
stop("Different number of parameters: class multinom, c(coef(fit)): ",
ncol(qhat), ", vcov(fit): ", ncol(ui))
u[i, , ] <- array(ui, dim = c(1, dim(ui)))
}
# ----------------------------------------------------
else {
qhat[i, ] <- coef(fit)
ui <- vcov(fit)
ui <- expandvcov(qhat[i, ], ui)
if (ncol(ui) != ncol(qhat))
stop("Different number of parameters: coef(fit): ",
ncol(qhat), ", vcov(fit): ", ncol(ui))
u[i, , ] <- array(ui, dim = c(1, dim(ui)))
}
}
qbar <- apply(qhat, 2, mean)
ubar <- apply(u, c(2, 3), mean)
e <- qhat - matrix(qbar, nrow = m, ncol = k, byrow = TRUE)
b <- (t(e) %*% e)/(m - 1)
t <- ubar + (1 + 1/m) * b
r <- (1 + 1/m) * diag(b/ubar)
lambda <- (1 + 1/m) * diag(b/t)
dfcom <- df.residual(object)
df <- mice.df(m, lambda, dfcom, method)
fmi <- (r + 2/(df + 3))/(r + 1)
names(r) <- names(df) <- names(fmi) <- names(lambda) <- names
fit <- list(call = call, call1 = object$call, call2 = object$call1,
nmis = object$nmis, m = m, qhat = qhat, u = u, qbar = qbar,
ubar = ubar, b = b, t = t, r = r, dfcom = dfcom, df = df,
fmi = fmi, lambda = lambda)
oldClass(fit) <- c("mipo", oldClass(object))
return(fit)
}
environment(pooly) <- environment(mice)
通过定义方法&:symbol
来工作。
以下是原始Ruby中定义的Symbol#to_proc
的示例:
http://maximomussini.com/posts/ruby-to_proc/
Symbol#to_proc
C版本添加了一个缓存,因此每次重新创建块都不会减慢我们的速度。
要获得您想要的内容,请定义class Symbol
def to_proc
->(obj, args = nil) { obj.send(self, *args) }
end
end
并拥有它!
答案 2 :(得分:1)
符号#to_proc可用作调用一个方法的基本情况的简写。如果你想要更复杂的东西,只需转移到手写
['Hi', 'Yo'].map { |word| [word.upcase, word.downcase] }
将返回[['HI', 'hi'], ['YO', 'yo']]
- 如果您想要的是flatten
,则可以调用['HI', 'hi', 'YO', 'yo']
。
更新:因为你真的想要[['HI','YO'], ['hi', 'yo']]
,你可以在结果上调用转置
['Hi', 'Yo'].map { |w| [w.upcase, w.downcase] }.transpose
注意:以下是一个可怕的想法,没有人应该在实际代码中实现它,因为Array#to_proc的含义是完全不明显的(它是否调用all并返回一个数组,是否链接,是否通过方法的参数等),但既然你已经要求它,你可以做类似
的事情class Array
def to_proc
lambda { |o| map { |m| o.send(m) } }
end
end
允许
['Hi', 'Yo'].map(&[:upcase, :downcase]).transpose
产生你要求的答案。它确实保存了几个字符,但它不值得添加到代码中的歧义。