How can I determine if an array contains some element? - julia

How can I tell if an array contains some element?
I have been manually checking with a loop:
for x in xs
if x == a
return true
end
end
return false
Is there a more idiomatic way?

The in operator will iterate over an array and check if some element exists:
julia> xs = [5, 9, 2, 3, 3, 8, 7]
julia> 8 in xs
true
julia> 1 in xs
false
It is important to remember that missing values can alter the behavior you might otherwise expect:
julia> 2 in [1, missing]
missing
in can be used on general collections. In particular, matrices:
julia> A = [1 4 7
2 5 8
3 6 9]
3×3 Array{Int64,2}:
1 4 7
2 5 8
3 6 9
julia> 7 in A
true
julia> 10 in A
false

Related

newline sensitive interpretation of Arrays

When I add a newline to my array definition, the type of my array changes.
julia> a = [[1]]
1-element Array{Array{Int64,1},1}:
[1]
julia> a = [[1]
]
1-element Array{Int64,1}:
1
I thought they both should return the same result i.e. of type Array{Array{Int64,1},1}
In order to understand this see the following:
julia> :([[1]
])
:([[1];])
And you see that adding a newline is rewritten as vcat operation.
The reason for this is to allow writing something like this:
julia> x = [1 2
3 4]
2×2 Array{Int64,2}:
1 2
3 4
and your example is hitting a corner case of this syntax.
Note, however, that without an extra empty line vcat is not called:
julia> :([[1]
])
:([[1]])
Another use-case that is worth to know is:
julia> [[1, 2]
[3, 4]]
4-element Array{Int64,1}:
1
2
3
4
and the same with variables (can improve code readability in some cases):
julia> a = [1,2]
2-element Array{Int64,1}:
1
2
julia> b = [3, 4]
2-element Array{Int64,1}:
3
4
julia> [a
b]
4-element Array{Int64,1}:
1
2
3
4

Find the tail of array except first element

Is there a method to get the tail of a collection(e.g. vector) i.e. the array except the first element. Currently, I have
tail(arr) = selectdim(arr, 1, 2:length(arr))
julia> c
3-element Array{Int64,1}:
1
2
3
julia> tail(c)
2-element view(::Array{Int64,1}, 2:3) with eltype Int64:
2
3
Simply use the end keyword:
julia> c = [11,12,13]
3-element Array{Int64,1}:
11
12
13
julia> c[2:end]
2-element Array{Int64,1}:
12
13

Equivalent of the dot prefix for an arbitrary function?

Julia allows me to do elementwise binary operators on arrays/matrices with .:
[1 2 3] .+ [3 2 1]
[1 2 3] .> [3 2 1]
Is there a standard way to apply an arbitrary function f elementwise to a pair of arrays?
If you just want to apply a binary function to each pair of values from two lists, you can use map:
f(x,y) = 2x - y^2
julia> map(f, [1, 2, 3], [3, 2, 1])
3-element Array{Int64,1}:
-7
0
5
The .+ and .> operators also have the additional behavior that singleton dimensions are broadcast, like so:
julia> [1, 2, 3] .+ [-1 -2 -3]
3x3 Array{Int64,2}:
0 -1 -2
1 0 -1
2 1 0
julia> rand(3,4) .+ [1, 2, 3]
3x4 Array{Float64,2}:
1.73798 1.84132 1.12923 1.30192
2.10961 2.17835 2.52779 2.3028
3.16457 3.04659 3.67604 3.08869
julia> rand(3,4) .+ [1 2 3 4]
3x4 Array{Float64,2}:
1.40294 2.31384 3.34001 4.60027
1.13289 2.99275 3.50606 4.51049
1.31486 2.7585 3.64655 4.59647
If you also want this kind of behavior, you can use the broadcast function:
julia> broadcast(f, [1 2 3], [3, 2, 1])
3x3 Array{Int64,2}:
-7 -5 -3
-2 0 2
1 3 5

Declare and initialise 3-dimensional array

I want to initialise a 3-dimensional array in Julia with constant entries. For the 2d case I can use
A = [1 2; 3 4]
Is there a similar short syntax for 3d arrays?
Not at this time, although something like the following isn't too bad
A = zeros(2,2,2)
A[:,:,1] = [1 2; 3 4]
A[:,:,2] = [10 20; 30 40]
One can use either the cat or the reshape functions to accomplish the task: (tested with Julia-1.0.0):
julia> cat([1 2; 3 4], [5 6; 7 8], dims=3)
2×2×2 Array{Int64,3}:
[:, :, 1] =
1 2
3 4
[:, :, 2] =
5 6
7 8
For higher Array dimensions, the cat calls must be nested: cat(cat(..., dims=3), cat(..., dims=3), dims=4).
The reshape function allows building higher dimension Arrays "at once", i.e., without nested calls:
julia> reshape([(1:16)...], 2, 2, 2, 2)
2×2×2×2 Array{Int64,4}:
[:, :, 1, 1] =
1 3
2 4
[:, :, 2, 1] =
5 7
6 8
[:, :, 1, 2] =
9 11
10 12
[:, :, 2, 2] =
13 15
14 16
It is actually possible to declare a multidimensional array in julia using only list comprehension
julia> a = [x + y + z for x in 1:2, y ∈ 2:3, z = 3:4]
2×2×2 Array{Int64,3}:
[:, :, 1] =
6 7
7 8
[:, :, 2] =
7 8
8 9
julia> size(a)
(2, 2, 2)
julia> ndims(a)
3
Julia documentation about Multi-dimensional Arrays is a good place to learn more about array creation.
For a 3-dimensional array, you can do the following:
julia> [1; 2;; 3; 4;; 5; 6;;;
7; 8;; 9; 10;; 11; 12]
2×3×2 Array{Int64, 3}:
[:, :, 1] =
1 3 5
2 4 6
[:, :, 2] =
7 9 11
8 10 12
From the documentation, "... ; and ;; concatenate in the first and second dimension, using more semicolons extends this same general scheme. The number of semicolons in the separator specifies the particular dimension, so ;;; concatenates in the third dimension, ;;;; in the 4th, and so on."

Convenient indexing to end of array

So I'm coming from Python where I can index until the end of an array by either omitting the end index. (Note that Python is 0-indexed):
In [1]: x = range(10)
In [2]: x
Out[2]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
In [3]: x[4:]
Out[3]: [4, 5, 6, 7, 8, 9]
In [4]: x[-6:]
Out[4]: [4, 5, 6, 7, 8, 9]
In [5]: x[-1]
Out[5]: 9
Also, negative indices start from the end of the array. In R, so far I've found that I need to do things like this:
> x <- 0:9
> x[5:length(x)]
[1] 4 5 6 7 8 9
and so on. Is there any sort of syntactic sugar for length(x)? (Perhaps something like end that MATLAB uses).
You could use the tail function instead of indexing.
In the following, the final 6 elements of the vector x are returned. 6 is the default return length for tail (and head, shown below), and the second argument changes that. So if you were to write tail(x, 5) for example, the final 5 elements will be returned.
> x <- 0:9
> tail(x)
# [1] 4 5 6 7 8 9
> tail(x, 5)
# [1] 5 6 7 8 9
Similarly, there is a head function for viewing the first few elements, which operates in the same manner.
> head(x)
# [1] 0 1 2 3 4 5
> head(x, 5)
# [1] 0 1 2 3 4
Logical indexing is one method. As mentioned (but not demonstrating the second argument to head or tail):
> x <- 1:10
> head(x,-3)
[1] 1 2 3 4 5 6 7
> tail(x,-3)
[1] 4 5 6 7 8 9 10
> x[x>=4]
[1] 4 5 6 7 8 9 10
Mixing negative and positive indices is not allowed.

Resources