I have tried deleteat!(arr, findfirst(item,arr)) but it gives me an error. Is it deprecated?
You can try popfirst!
if you just want to remove the first element of the array.
You probably want:
findfirst(isequal(item), arr)
to get the index of the first item which is equal to item
.
This behavior changed in Julia 1.0, so if you have other old code you might find that running it in Julia 0.7 is helpful, since it will tell you exactly what changed and how to fix your code:
julia-0.7> findfirst(1, [1, 2, 3])
┌ Warning: `findfirst(A, v)` is deprecated, use `something(findfirst(isequal(v), A), 0)` instead.
│ caller = top-level scope at none:0
└ @ Core none:0
0
findfirst(isequal(item), arr)
gives me the error LoadError: MethodError: no method matching iterate(::Nothing)
Here is the block of code where it is for some context:
coord = [(i, j) for i = 1:3 for j = 1:3]
corners = [(i, j) for i = 1:2:3 for j = 1:2:3]
for i = 1:3
for j = 1:3
(i, j) in coord ? deleteat!(corners, findfirst(isequal((i, j)), corners)) :
push!(coord, (i, j))
end
end
It’s not the completed code, but this is the general part that the issue is in…
Also how would you run julia 0.7 in the REPL?
Presumably this error happens when you call deleteat!
with that result? It’s much easier to help if you can provide a way to actually reproduce the error and/or a complete backtrace.
I assume that what’s happening is that arr
does not contain item
. In that case, findfirst
returns nothing
:
julia> arr = [1, 2, 3]
3-element Array{Int64,1}:
1
2
3
julia> findfirst(isequal(4), arr)
julia> findfirst(isequal(4), arr) === nothing
true
And deleteat!
does not accept nothing
(unsurprisingly):
julia> deleteat!(arr, findfirst(isequal(4), arr))
ERROR: MethodError: no method matching iterate(::Nothing)
Note that you get an error in python as well:
In [1]: [1, 2, 3].remove(5)
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-1-c5f0d54cbcf3> in <module>()
----> 1 [1, 2, 3].remove(5)
ValueError: list.remove(x): x not in list
although admittedly it’s more obvious.
There may not be a built-in function that does exactly what you want in this case. You might need to write one:
function remove!(collection::AbstractVector, item)
index = findfirst(isequal(item), collection)
if index === nothing
error("$item is not in $collection")
else
deleteat!(collection, index)
end
end
julia> arr = [1, 2, 3]
3-element Array{Int64,1}:
1
2
3
julia> remove!(arr, 1)
2-element Array{Int64,1}:
2
3
julia> arr
2-element Array{Int64,1}:
2
3
julia> remove!(arr, 4)
ERROR: 4 is not in [2, 3]
To run a new Julia version, you need to download it from https://julialang.org/downloads/oldreleases.html and then just ensure it’s available on your path. I wrote up my personal workflow for dealing with multiple Julia versions here: Transitioning from Ubuntu PPA to official binaries - #2 by rdeits and I’ve been pretty happy with it.
Isn’t this the function delete!
?
This gives the error MethodError: no method matching findfirst(::Bool, ::Array{Tuple{Int64,Int64},2})
Does delete!
work with arrays? It gives me an error and the docs only mentions dictionaries/idsets
Ah no, apparently not, as methods(delete!)
shows. (I wasn’t at my computer.)
You need to post a minimal working example to get better help: exactly what input and what output do you need?
@dpsanders
Here is one instance of when I want to use it. I am doing a tic tac toe program and I want to iterate through the corners
# Corner check
corners = [(i, j) for i = 1:2:3 for j = 1:2:3]
while length(corners) > 1
corner_choice = corners[rand(1:length(corners))]
if corner_choice in coord
board[corner_choice[1], corner_choice[2]] = current_player
return
else
deleteat!(corners, findfirst(isequal(corner_choice), corners))
end
end
When you make the choice of a random element in the list, you are choosing the index. Just store that and use it.
@dpsanders
That approach wouldn’t work for this part though… (checking for spaces and updating a separate array with coordinates)
for i = 1:3
for j = 1:3
if board[i, j] == " "
if (i, j) in coord
deleteat!(coord, findfirst(isequal(i, j), coord))
else
push!(coord, (i, j))
end
end
end
end
I ended up using a work around by iterating with a pairs()
function and generating the tuple coordinate with math.