Julia the most efficient way to select the longest array in an array of arrays?

I have an array of arrays A , which is an N-element Array{Array{Int64,1},1} integers. I am trying to find the largest array in A using Julia.

For instance:

 A = [[1, 2], [3, 4], [5, 6, 7], [1, 2, 5, 8]] 

In Python, I would just do: max(A, key=len) , but in Julia I don't know how to do this.

I have done the following:

 L = [] for a in A push!(L, length(a)) end A[findmax(L)[2]] 

Thanks!

+5
source share
2 answers

EDIT: Note. Also worth checking out another answer at @crstnbr

Consider the following code example:

 julia> A = [[1,2], [1,2,3,4,5,6], [1,2,3]] 3-element Array{Array{Int64,1},1}: [1, 2] [1, 2, 3, 4, 5, 6] [1, 2, 3] julia> length(A) 3 julia> length.(A) 3-element Array{Int64,1}: 2 6 3 julia> indmax(length.(A)) 2 julia> A[indmax(length.(A))] 6-element Array{Int64,1}: 1 2 3 4 5 6 

The first call to length gets the length of the outer vector in A , which we donโ€™t want. In the second call, I use the broadcast operator . to get the length of each of the inner vectors instead. In the indmax line indmax I find the index of the largest value in length.(A) , i.e. Index of the longest inner vector. If you want to return the longest inner vector, you can simply index it on A using the result of the indmax string.

+6
source

@Colin provided a compact, convenient answer. However, if speed matters (the operator is offered the most efficient way), this should be close to optimal

 function findlongest(A) idx = 0 len = 0 @inbounds for i in 1:length(A) l = length(A[i]) l > len && (idx = i; len=l) end return A[idx] end 

Note that this implementation (presumably) would be a very bad idea in Python :)

Quick test:

 julia> using BenchmarkTools julia> A = [[1,2], [1,2,3,4,5,6], [1,2,3]] 3-element Array{Array{Int64,1},1}: [1, 2] [1, 2, 3, 4, 5, 6] [1, 2, 3] julia> @btime findlongest(A); 26.880 ns (0 allocations: 0 bytes) julia> @btime A[indmax(length.(A))]; 9.813 ฮผs (25 allocations: 1.14 KiB) 

In this example, ~ 365 times faster .

EDIT: Best test (suggested in the comments)

 julia> @btime findlongest($A); 9.813 ns (0 allocations: 0 bytes) julia> @btime $A[indmax(length.($A))]; 41.813 ns (1 allocation: 112 bytes) 

The $ signs do not allow settings and time. Acceleration ~ 4.

Short description

  • for loops fast in Julia so why not use them
  • avoid selection ( length.(A) allocates a new array of integers)
  • a && b is a shortcut for "if a then b"
  • @inbounds avoids related checks for A[i]
+6
source

Source: https://habr.com/ru/post/1274513/


All Articles