Удалить элемент в массиве для Юлии

Некоторое время я бродил в документах и ​​на форумах, и я не нашел встроенного метода / функции для выполнения простой задачи удаления элемента в массиве. Есть ли такая встроенная функция?

Я прошу эквивалент списка 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! индексы становятся недействительными, поэтому вам необходимо обновить их.

Другие вопросы по тегам