From f40832dc2cfc2d7228ce5d9f5d8030cc0397e646 Mon Sep 17 00:00:00 2001 From: Milan Bouchet-Valat Date: Thu, 7 Dec 2017 13:52:40 +0100 Subject: [PATCH 1/2] Use three-valued logic with missing values in ==(::Tuple, ::Tuple) For consistency with AbstractArray. --- base/tuple.jl | 12 ++++++++---- test/missing.jl | 12 ++++++++++++ 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/base/tuple.jl b/base/tuple.jl index 2b94d1d946e44..e614a89518223 100644 --- a/base/tuple.jl +++ b/base/tuple.jl @@ -268,12 +268,16 @@ function ==(t1::Tuple, t2::Tuple) if length(t1) != length(t2) return false end + anymissing = false for i = 1:length(t1) - if !(t1[i] == t2[i]) - return false - end + eq = (t1[i] == t2[i]) + if ismissing(eq) + anymissing = true + elseif !eq + return false + end end - return true + return anymissing ? missing : true end const tuplehash_seed = UInt === UInt64 ? 0x77cfa1eef01bca90 : 0xf01bca90 diff --git a/test/missing.jl b/test/missing.jl index a2ea8e3b1eaba..a2670f6c106d2 100644 --- a/test/missing.jl +++ b/test/missing.jl @@ -222,6 +222,18 @@ end @test Union{Int, Missing}[1] != Union{Int, Missing}[2] end +@testset "== and != on tuples" begin + @test ismissing((1, missing) == (1, missing)) + @test ismissing(("a", missing) == ("a", missing)) + @test ismissing((missing,) == (missing,)) + @test ismissing((missing, 2) == (1, missing)) + + @test ismissing((1, missing) != (1, missing)) + @test ismissing(("a", missing) != ("a", missing)) + @test ismissing((missing,) != (missing,)) + @test ismissing((missing, 2) != (1, missing)) +end + @testset "any & all" begin @test any([true, missing]) @test any(x -> x == 1, [1, missing]) From be38d94275fcd66b9276019170dbeee4c6607f0f Mon Sep 17 00:00:00 2001 From: Milan Bouchet-Valat Date: Thu, 7 Dec 2017 14:23:04 +0100 Subject: [PATCH 2/2] Add equality test returning false even in the presence of missings --- test/missing.jl | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/missing.jl b/test/missing.jl index a2670f6c106d2..81b09667dd1d0 100644 --- a/test/missing.jl +++ b/test/missing.jl @@ -202,6 +202,7 @@ end @test Union{Int, Missing}[1] == Union{Float64, Missing}[1.0] @test Union{Int, Missing}[1] == [1.0] @test Union{Bool, Missing}[true] == BitArray([true]) + @test !([missing, 1] == [missing, 2]) @test !(Union{Int, Missing}[1] == [2]) @test !([1] == Union{Int, Missing}[2]) @test !(Union{Int, Missing}[1] == Union{Int, Missing}[2]) @@ -217,6 +218,7 @@ end @test !(Union{Int, Missing}[1] != Union{Float64, Missing}[1.0]) @test !(Union{Int, Missing}[1] != [1.0]) @test !(Union{Bool, Missing}[true] != BitArray([true])) + @test [missing, 1] != [missing, 2] @test Union{Int, Missing}[1] != [2] @test [1] != Union{Int, Missing}[2] @test Union{Int, Missing}[1] != Union{Int, Missing}[2] @@ -227,11 +229,13 @@ end @test ismissing(("a", missing) == ("a", missing)) @test ismissing((missing,) == (missing,)) @test ismissing((missing, 2) == (1, missing)) + @test !((missing, 1) == (missing, 2)) @test ismissing((1, missing) != (1, missing)) @test ismissing(("a", missing) != ("a", missing)) @test ismissing((missing,) != (missing,)) @test ismissing((missing, 2) != (1, missing)) + @test (missing, 1) != (missing, 2) end @testset "any & all" begin