Удалить элемент в массиве для Юлии
Некоторое время я бродил в документах и на форумах, и я не нашел встроенного метода / функции для выполнения простой задачи удаления элемента в массиве. Есть ли такая встроенная функция?
Я прошу эквивалент списка python list.remove(x).
Вот пример наивного выбора функции из коробки:
julia> a=Any["D","A","s","t"]
julia> pop!(a, "s")
ERROR: MethodError: `pop!` has no method matching
pop!(::Array{Any,1}, ::ASCIIString)
Closest candidates are:
pop!(::Array{T,1})
pop!(::ObjectIdDict, ::ANY, ::ANY)
pop!(::ObjectIdDict, ::ANY)
...
Здесь упоминается для использования deleteat!
, но также не работает:
julia> deleteat!(a, "s")
ERROR: MethodError: `-` has no method matching -(::Int64, ::Char)
Closest candidates are:
-(::Int64)
-(::Int64, ::Int64)
-(::Real, ::Complex{T<:Real})
...
in deleteat! at array.jl:621
3 ответа
Вы также можете пойти с filter!
:
a = Any["D", "A", "s", "t"]
filter!(e->e≠"s",a)
println(a)
дает:
Any["D","A","t"]
Это позволяет удалить несколько значений одновременно, как в:
filter!(e->e∉["s","A"],a)
Примечание 1: В Julia 0.5 анонимные функции выполняются намного быстрее, и небольшое ухудшение в 0,4 больше не является проблемой:-) .
Примечание 2: Код выше использует операторы Юникод. С обычными операторами: ≠
является !=
а также e∉[a,b]
является !(e in [a,b])
Несколько других ответов устарели из-за более поздних выпусков Джулии. Я сейчас (Юлия 1.1.0) использую что-то вроде
function remove!(a, item)
deleteat!(a, findall(x->x==item, a))
end
Вы также можете использовать findfirst
если вы предпочитаете, но это не работает, если a
не содержит item
,
deleteat!
+ findin
сделаю это:
a = Any["D", "A", "s", "t"]
deleteat!(a, findin(a, ["s"])) # => ["D", "A", "t"]
это потому что pop!
не имеет метода для удаления определенного элемента в массиве, он только удаляет последний, и deleteat!
нужен индекс элемента, который вы хотите исключить. Вы можете проверить методы, которые есть у функции methods
:
methods(pop!)
methods(deleteat!)
Для Dict
Вы можете подать ключ элемента, чтобы исключить delete!
,
В зависимости от использования, это также полезно знать setdiff
и это на месте версия setdiff!
:
julia> setdiff([1,2,3,4], [3])
3-element Array{Int64,1}:
1
2
4
Однако обратите внимание, что он также удаляет все повторяющиеся элементы, как показано в примере:
julia> setdiff!([1,2,3,4, 4], [3])
3-element Array{Int64,1}:
1
2
4
Ты можешь использовать deleteat!
а также findall
(совместим с Julia>1.0) для этого.
a=Any["D","A","s","t","s"]
deleteat!(a, findall(x->x=="s",a))
Выход:
3-element Array{Any,1}:
"D"
"A"
"t"
Более свежие ответы хороши. Однако использование функции find___ для поиска удаляемого элемента с помощью deleteat!() Очень неэффективно. Я обнаружил, что мой код, использующий это, занял в 100 раз больше времени, чем нужно, исключительно потому, что я использовал этот метод!
Другой подход - создать словарь элементов и их индексов, чтобы при необходимости их можно было просто найти.
items # vector of items
itemindexes = IdDict(zip(items, eachindex(items))
todelete = Int[]
# do stuff and record indexes to delete with push!(todelete, <indexhere>)
sort!(todelete) # has to be in increasing order
deleteat!(items, todelete)
Очевидно, что после использования deleteat! индексы становятся недействительными, поэтому вам необходимо обновить их.