检查 Julia 数组的所有元素是否相等

问题描述 投票:0回答:4

我能想到的测试数组

arr
中所有元素是否相等的最短方法是
all(arr[1] .== arr)
。虽然这确实很短,但似乎有点不优雅。有内置函数可以做到这一点吗?

我怀疑有类似

==(arr...)
的东西,但这不起作用,因为
==
运算符只能接受两个参数。我不确定 Julia 如何解析像
arr[1] == arr[2] == arr[3]
这样的表达式,但是有没有办法让它适应具有任意数量元素的数组?

arrays julia equality
4个回答
18
投票

很好的问题@tparker 和很好的答案@ColinTBowers。当我试图思考这两个问题时,我突然想到尝试一下“直接的老派朱利安方法”“for

循环”。在相同元素的长向量的重要输入上,结果更快,因此我添加了此注释。另外,函数名称
allequal似乎足够合适提及。所以这里是变体:

allequal_1(x) = all(y->y==x[1],x) # allequal_2(x) used to be erroneously defined as foldl(==,x) @inline function allequal_3(x) length(x) < 2 && return true e1 = x[1] i = 2 @inbounds for i=2:length(x) x[i] == e1 || return false end return true end

和基准:

julia> using BenchmarkTools julia> v = fill(1,10_000_000); # long vector of 1s julia> allequal_1(v) true julia> allequal_3(v) true julia> @btime allequal_1($v); 9.573 ms (1 allocation: 16 bytes) julia> @btime allequal_3($v); 6.853 ms (0 allocations: 0 bytes)

更新:另一个重要的基准测试案例是当存在短路机会时。所以(根据评论中的要求):

julia> v[100] = 2 2 julia> allequal_1(v),allequal_2(v),allequal_3(v) (false, false, false) julia> @btime allequal_1($v); 108.946 ns (1 allocation: 16 bytes) julia> @btime allequal_3($v); 68.221 ns (0 allocations: 0 bytes)

在所有条件相同的情况下,
for

版本在 Base 中应该是

allequal
    


18
投票
all

是正确的解决方案,但您需要谓词

all(p, itr)
和可迭代
p
的方法
itr
,因为它将采用短路行为(一旦发现
false
就中断)。所以:

all(y->y==x[1], x)

要查看差异,您可以运行以下小速度测试:

for n = 100000:250000:1100000 x = rand(1:2, n); @time all(x .== x[1]); @time all(y->y==x[1], x); println("------------------------") end

忽略第一次迭代,因为它正在计时编译时间。

0.000177 seconds (22 allocations: 17.266 KiB) 0.006155 seconds (976 allocations: 55.062 KiB) ------------------------ 0.000531 seconds (23 allocations: 47.719 KiB) 0.000003 seconds (1 allocation: 16 bytes) ------------------------ 0.000872 seconds (23 allocations: 78.219 KiB) 0.000001 seconds (1 allocation: 16 bytes) ------------------------ 0.001210 seconds (23 allocations: 108.781 KiB) 0.000001 seconds (1 allocation: 16 bytes) ------------------------ 0.001538 seconds (23 allocations: 139.281 KiB) 0.000002 seconds (1 allocation: 16 bytes)

第一个解决方案显然是 O(n),而第二个解决方案最好是 O(1),最坏是 O(n)(取决于 
itr

的数据生成过程)。

    


15
投票
allsame(x) = all(y -> y == first(x), x)

allsame(x) = all(y -> y == x[1], x)
更通用,即使当
x
不是
AbstractArray
时也可以工作,例如发电机。
    


0
投票

allequal(arr)

或者1.8之前,您可以简单地检查:

length(unique(arr)) == 1

© www.soinside.com 2019 - 2024. All rights reserved.