Trying to understand sort!(), findfirst()

So far, this community is giving a lot of helps to answer beginner level julialang question. I am still in the early stage of learning julialang, so here I got a few new questions that might need community help. I am a little confused about using `sort!()`, `findfirst()` function. Here is the code line that I got stuck:

``````for i=1:n:
ps_id=[] # psid::Vector[Int]
cns = [] # cns::Tuple{Integer, Vector}[]
cs = (i, sort!(ps_id))
if findfirst(cns .== cs) ==0
push!(cns, cs)
end
end
``````

Does anyone provide possible examples to understand the above codes explicitly? what’s the corresponding pythonic code for those? Any thoughts?

since I am more comfortable with python, so this is my attempt to do same thing in pythonic way:

``````for i in range(1, n):
ps_id=[] # psid::Vector[Int]
cns = [] # cns::Tuple{Integer, Vector}[]
# cs = (i, sort!(ps_id)) # julialang
cs = np.sort(ps_id[i]) # I am not quire sure this pythonic way
if findfirst(cns .== cs) ==0
cns.append(cs)
``````

in my pythonic attempt, I am not quite sure I did right for pythonic code such as `cs = np.sort(ps_id[i])` is actually as same as `cs = (i, sort!(ps_id))`. Can anyone point me out `sort!()` function bit clear?

I think I got confused about using `findfirst()` in julialang, not sure how should I do same thing in python? Does anyone have better ideas? Thanks!

I’m not exactly clear on what your question is, but the following examples might be helpful

``````julia> x=randn(5)
5-element Array{Float64,1}:
0.7434739264175095
-0.3395323336044915
0.13788529694661847
-0.27519785275734027
1.0434216847847444

julia> sort!(x)
5-element Array{Float64,1}:
-0.3395323336044915
-0.27519785275734027
0.13788529694661847
0.7434739264175095
1.0434216847847444

julia> x
5-element Array{Float64,1}:
-0.3395323336044915
-0.27519785275734027
0.13788529694661847
0.7434739264175095
1.0434216847847444

julia> isone
isone (generic function with 13 methods)

julia> findfirst(isone, x .< 0.0)
1

julia> findfirst(isone, x .> 0.0)
3

``````
1 Like

Thanks for the heads up. I am trying to understand the julia code with pythonic alternative, such as `cs=(i, sort!(ps_id))` is as same as this pythonic code: `cs=np.sort(ps_id[i])`. I am not sure role of `findfirst()` in if condiction: `if findfirst(cns .==cs)==0`. Do you have any clue this can be written in the plain pythonic way? what is the meaning of `.==`? any idea?

compares cns and cs for equality, takes the first thing that does NOT match, i.e. the first item that is NOT in cns, and adds that to the array cns. Or at least I’m pretty sure that’s what it does.

.== automatically applies the ‘==’ operator to arrays. The ‘.’ notation is important to understand, please see

1 Like

To add to @purplishrock’s answers, you can check functions’ docs by typing `?` at the REPL (to go in “help” mode) and get some helpful info on the function. For example,

``````help?> sort!
search: sort! partialsort! sortperm! partialsortperm! setproperty! sort sortperm sortslices SortedSet sorted_rank SortedDict

sort!(v; alg::Algorithm=defalg(v), lt=isless, by=identity, rev::Bool=false, order::Ordering=Forward)

Sort the vector v in place. QuickSort is used by default for numeric arrays while MergeSort is used for other arrays. You
can specify an algorithm to use via the alg keyword (see Sorting Algorithms for available algorithms). The by keyword lets
you provide a function that will be applied to each element before comparison; the lt keyword allows providing a custom
"less than" function; use rev=true to reverse the sorting order. These options are independent and can be used together in
all possible combinations: if both by and lt are specified, the lt function is applied to the result of the by function;
rev=true reverses whatever ordering specified via the by and lt keywords.
# and much more (cut for clarity, but try it yourself)
``````

To your specific questions, maybe an example with `Int`s is clearer. The Julia functions `sort!` and `findfirst` are pretty much explicit:

• `sort!(x)` sorts `x` by mutating it (the `!` at the end indicates mutation):

``````julia> x = rand(1:1000, 5)
5-element Array{Int64,1}:
200
247
15
878
441

julia> sort!(x); x
5-element Array{Int64,1}:
15
200
247
441
878
``````
• `findfirst(y)` finds the first index of `y` that is `true`. I can use `.==` to find the first element equal to some value (the dot `.` means element-wise and `==` means “is equal”, so `.==` means it tests equality of each element against what is on the other side). For example, I can find the first element equal to `2` with `findfirst(x .== 2)`, as in this example:

``````julia> x = rand(1:3, 5)
5-element Array{Int64,1}:
3
2
2
3
3

julia> x .== 2
5-element BitArray{1}:
0
1
1
0
0

julia> findfirst(x .== 2)
2
``````

Alternatively, I can have a function as the first argument of `findfirst`, and Julia will apply that function to the array as it looks for that first index. Here I could use the function `==(2)` which is testing equality with `2`:

``````julia> findfirst(==(2), x)
2
``````

but I personally prefer the `findfirst(x .== 2)` version.

Otherwise, note that in your code

``````findfirst(cns .== cs) == 0
``````

will never return `true` since indexing start at `1` in Julia (so `findfirst` can only return an integer greater or equal to `1`, or `nothing` if no element is found).

4 Likes