2016-01-31 10 views
5

Ho creato un array unidimensionale (vettore) in Julia, ovvero a=[1, 2, 3, 4, 5]. Quindi voglio creare un nuovo vettore b, dove b ha esattamente gli stessi elementi in a, cioè b=[1, 2, 3, 4, 5].Copia o clona una raccolta in Julia

Sembra che utilizzano direttamente b = a basta creare un puntatore per la raccolta originale, che significa che se modifico b e a è mutevole, la modifica si rifletterà anche in a. Ad esempio, se utilizzo !pop(b), quindi b=[1, 2, 3, 4] e a=[1, 2, 3, 4].

Mi chiedo se esiste una funzione ufficiale per copiare o clonare semplicemente la raccolta, che la modifica in b non si verificherà in a. Trovo una soluzione è utilizzare b = collect(a). Gradirei che qualcuno fornisse altri approcci.

+0

sei venuto dalla lingua R giusto? – colinfang

+0

@colinfang, non esattamente. Ma come biostatista devo usare R per lavorare con i collaboratori. – Conta

risposta

8

b=copy(a)

dovrebbe fare quello che vuoi.

methods(copy) ti fornirà un elenco di metodi per copy, che ti indicheranno i tipi di a per cui funzionerà.

julia> methods(copy) 
# 32 methods for generic function "copy": 
copy(r::Range{T}) at range.jl:324 
copy(e::Expr) at expr.jl:34 
copy(s::SymbolNode) at expr.jl:38 
copy(x::Union{AbstractString,DataType,Function,LambdaStaticData,Number,QuoteNode,Symbol,TopNode,Tuple,Union}) at operators.jl:194 
copy(V::SubArray{T,N,P<:AbstractArray{T,N},I<:Tuple{Vararg{Union{AbstractArray{T,1},Colon,Int64}}},LD}) at subarray.jl:29 
copy(a::Array{T,N}) at array.jl:100 
copy(M::SymTridiagonal{T}) at linalg/tridiag.jl:63 
copy(M::Tridiagonal{T}) at linalg/tridiag.jl:320 
copy{T,S}(A::LowerTriangular{T,S}) at linalg/triangular.jl:36 
copy{T,S}(A::Base.LinAlg.UnitLowerTriangular{T,S}) at linalg/triangular.jl:36 
copy{T,S}(A::UpperTriangular{T,S}) at linalg/triangular.jl:36 
copy{T,S}(A::Base.LinAlg.UnitUpperTriangular{T,S}) at linalg/triangular.jl:36 
copy{T,S}(A::Symmetric{T,S}) at linalg/symmetric.jl:38 
copy{T,S}(A::Hermitian{T,S}) at linalg/symmetric.jl:39 
copy(M::Bidiagonal{T}) at linalg/bidiag.jl:113 
copy(S::SparseMatrixCSC{Tv,Ti<:Integer}) at sparse/sparsematrix.jl:184 
copy{Tv<:Float64}(A::Base.SparseMatrix.CHOLMOD.Sparse{Tv<:Float64}, stype::Integer, mode::Integer) at sparse/cholmod.jl:583 
copy(A::Base.SparseMatrix.CHOLMOD.Dense{T<:Union{Complex{Float64},Float64}}) at sparse/cholmod.jl:1068 
copy(A::Base.SparseMatrix.CHOLMOD.Sparse{Tv<:Union{Complex{Float64},Float64}}) at sparse/cholmod.jl:1069 
copy(a::AbstractArray{T,N}) at abstractarray.jl:349 
copy(s::IntSet) at intset.jl:34 
copy(o::ObjectIdDict) at dict.jl:358 
copy(d::Dict{K,V}) at dict.jl:414 
copy(a::Associative{K,V}) at dict.jl:204 
copy(s::Set{T}) at set.jl:35 
copy(b::Base.AbstractIOBuffer{T<:AbstractArray{UInt8,1}}) at iobuffer.jl:38 
copy(r::Regex) at regex.jl:65 
copy(::Base.DevNullStream) at process.jl:98 
copy(C::Base.LinAlg.Cholesky{T,S<:AbstractArray{T,2}}) at linalg/cholesky.jl:160 
copy(C::Base.LinAlg.CholeskyPivoted{T,S<:AbstractArray{T,2}}) at linalg/cholesky.jl:161 
copy(J::UniformScaling{T<:Number}) at linalg/uniformscaling.jl:17 
copy(A::Base.SparseMatrix.CHOLMOD.Factor{Tv}) at sparse/cholmod.jl:1070 
+1

Grazie a Shashi, il 'copy()' aiuta davvero ed è quello che sto cercando. Ho appena trovato che è documentato nella sezione di matrice multidimensionale ma non nella sezione Raccolta e struttura dei dati del documento di Julia – Conta

4

Offriamo le copy e deepcopy funzioni:

help?> copy 
search: copy copy! copysign deepcopy unsafe_copy! cospi complex Complex complex64 complex32 complex128 complement 

    copy(x) 

    Create a shallow copy of x: the outer structure is copied, but not all internal values. For example, copying an 
    array produces a new array with identically-same elements as the original. 

help?> deepcopy 
search: deepcopy 

    deepcopy(x) 

    Create a deep copy of x: everything is copied recursively, resulting in a fully independent object. For example, 
    deep-copying an array produces a new array whose elements are deep copies of the original elements. Calling deepcopy 
    on an object should generally have the same effect as serializing and then deserializing it. 

    As a special case, functions can only be actually deep-copied if they are anonymous, otherwise they are just copied. 
    The difference is only relevant in the case of closures, i.e. functions which may contain hidden internal 
    references. 

    While it isn't normally necessary, user-defined types can override the default deepcopy behavior by defining a 
    specialized version of the function deepcopy_internal(x::T, dict::ObjectIdDict) (which shouldn't otherwise be used), 
    where T is the type to be specialized for, and dict keeps track of objects copied so far within the recursion. 
    Within the definition, deepcopy_internal should be used in place of deepcopy, and the dict variable should be 
    updated as appropriate before returning. 

Ti piace questa:

julia> a = Any[1, 2, 3, [4, 5, 6]] 
4-element Array{Any,1}: 
1  
2  
3  
    [4,5,6] 

julia> b = copy(a); c = deepcopy(a); 

julia> a[4][1] = 42; 

julia> b # copied 
4-element Array{Any,1}: 
1 
2 
3 
    [42,5,6] 

julia> c # deep copied 
4-element Array{Any,1}: 
1 
2 
3 
    [4,5,6] 

Si noti che i suggerimenti di aiuto di sistema per l'esistenza di altre funzioni di copia correlati.