X=[f(i) for i in 1:1:100 if (j=f(i) ;j < 0.5 ? false: j>0.5)]
这个问题是它调用了f(x)的两个独立实例,并且因为f(x)每次都是随机的,所以上面不会在正确的实例中杀死for循环.我试过了
X=[J=f(i) for i in 1:1:100 if (J < 0.5 ? false: J>0.5)]
作为尝试保存特定的随机数,但它告诉我J没有定义.有没有办法保存这个特定的随机数来执行我的数组理解?
X = ( r=Vector{Float64}() ; any(i->(v=f(i) ; v>0.5 ? ( push!(r,v) ; false) : true), 1:100) ; r )
[单行被分成三行,因为它有点长;)]
由于缺少f,要测试此版本使用rand复制粘贴此版本:
(r=ones(0); any(i->(v=rand(); v>0.5 ? (push!(r,v); false) : true), 1:10); r)
它的基准测试比凤阳的功能慢了约10%.聪明的一点是利用任何短路实现.
附录:这里概括一下凤阳的一个版本需要抽象出这个问题的答案:
collectwhilecond(f,cond,itr) = begin r=Vector{typeof(f(first(itr)))}() all(x->(y=f(x); cond(y) ? (push!(r,y);true):false),itr) return r end
现在,我们可以实现上面的答案(用joker作为f):
julia> joker(i) = 1.0 + 4*rand() - log(i) julia> collectwhilecond(joker, x->x>=0.5, 1:100) 3-element Array{Float64,1}: 4.14222 3.42955 2.76387
如果Julia推断f的返回类型,collectwhilecond也是类型稳定的.
编辑:使用@ tim建议的方法推断f的返回类型而不拉动itr的元素并且没有冒险产生错误的不稳定f,新的collectwhilecond是:
collectwhilecond(f,cond,itr) = begin t = Base.promote_op(f,eltype(itr)) # unofficial and subject to change r = Vector{t}() all( x -> ( y=f(x) ; cond(y) ? (push!(r,y) ; true) : false), itr ) return r end