One fix is to track deleted items to prevent them from being re-added.
function onlyoneof2(F)
Ft = sort.(SVector{4}.(eachrow(F)))
d = Dict{eltype(Ft),Int}()
del = Vector{eltype(Ft)}()
for i in eachindex(Ft)
if haskey(d, Ft[i])
delete!(d, Ft[i])
push!(del, Ft[i])
elseif Ft[i] β del
continue
else
d[Ft[i]] = i
end
end
return collect(values(d))
end
Now if we modify the short F
you gave to have an odd number of occurrences of a row: Fβ²=[1 2 3 4; 5 6 7 8; 4 3 2 1; 7 8 6 5; 1 2 5 6; 8 7 6 5; 5 6 7 8;1 2 3 4;]
.
julia> onlyoneof(F)
2-element Vector{Int64}:
5
8 # wrong
julia> onlyoneof2(F)
1-element Vector{Int64}:
5
Iβm surprised (and somewhat confused) to find that this new version is faster!
julia> @benchmark onlyoneof(F4) evals=5
BenchmarkTools.Trial: 6531 samples with 5 evaluations.
Range (min β¦ max): 136.330 ΞΌs β¦ 470.626 ΞΌs β GC (min β¦ max): 0.00% β¦ 59.64%
Time (median): 141.526 ΞΌs β GC (median): 0.00%
Time (mean Β± Ο): 152.676 ΞΌs Β± 50.194 ΞΌs β GC (mean Β± Ο): 6.92% Β± 12.69%
ββββ ββ β
βββββββ
ββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
136 ΞΌs Histogram: log(frequency) by time 384 ΞΌs <
Memory estimate: 405.27 KiB, allocs estimate: 210.
julia> @benchmark onlyoneof2(F4) evals=5
BenchmarkTools.Trial: 9865 samples with 5 evaluations.
Range (min β¦ max): 89.992 ΞΌs β¦ 308.097 ΞΌs β GC (min β¦ max): 0.00% β¦ 64.94%
Time (median): 95.344 ΞΌs β GC (median): 0.00%
Time (mean Β± Ο): 100.918 ΞΌs Β± 31.735 ΞΌs β GC (mean Β± Ο): 5.52% Β± 11.16%
ββββ ββ β β
ββββββββ
ββββββββ
βββββββββββββββββββββββββββββββββββββββββββββ β
90 ΞΌs Histogram: log(frequency) by time 280 ΞΌs <
Memory estimate: 286.78 KiB, allocs estimate: 15.