Map! - but it didn't map!

I’ m still at the basics, so I wonder why line 2 works fine, but line 3 doesn’t:

1)—listofnumbers = [23, 45, 56, 67, 89]
2)—listofnumbers = map(x -> x + 1, listofnumbers)
3)—map!(x -> x + 1, listofnumbers)
4)—println(listofnumbers)

I got the following message, but I still don’t know what’s wrong with line number 3:

ERROR: LoadError: BoundsError: attempt to access ()
at index [1]
Stacktrace:
[1] getindex(::Tuple, ::Int64) at .\tuple.jl:24
[2] map_n!(::var"#33#34", ::Array{Int64,1}, ::Tuple{}) at .\abstractarray.jl:2123
[3] map!(::var"#33#34", ::Array{Int64,1}) at .\abstractarray.jl:2152
[4] top-level scope at C:\julia\Julia-1.3.1\examples\extra001.jl:10
[5] include at .\boot.jl:328 [inlined]
[6] include_relative(::Module, ::String) at .\loading.jl:1105
[7] include(::Module, ::String) at .\Base.jl:31
[8] include(::String) at .\client.jl:424
[9] top-level scope at none:0
in expression starting at C:\julia\Julia-1.3.1\examples\extra001.jl:10

Hello,

The first step is always to check the help

help?> map!
search: map! asyncmap! map_coefficients_inplace! map mapcols mapfoldr mapfoldl map_rows mapslices mapreduce map_coefficients

  map!(function, destination, collection...)

  Like map, but stores the result in destination rather than a new collection. destination must be at least as large as the 
  first collection.

  Examples
  ≡≡≡≡≡≡≡≡≡≡

  julia> a = zeros(3);
  
  julia> map!(x -> x * 2, a, [1, 2, 3]);
  
  julia> a
  3-element Array{Float64,1}:
   2.0
   4.0
   6.0

  ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────  

  map!(f, values(dict::AbstractDict))

  Modifies dict by transforming each value from val to f(val). Note that the type of dict cannot be changed: if f(val) is not  
  an instance of the key type of dict then it will be converted to the key type if possible and otherwise raise an error.      

  Examples
  ≡≡≡≡≡≡≡≡≡≡

  ```jldoctest julia> d = Dict(:a => 1, :b => 2) Dict{Symbol,Int64} with 2 entries: :a => 1 :b => 2

  julia> map!(v -> v-1, values(d)) Dict{Symbol,Int64} with 2 entries: :a => 0 :b => 1 ```

Based on the above, we need a destination for map! (the ! symbol stands for in-place operations so it doesn’t allocate a new array for storing the result. It just mutates the existing array.).

What you need then is

julia> listofnumbers = [23, 45, 56, 67, 89]
5-element Array{Int64,1}:
 23
 45
 56
 67
 89

julia> map!(x -> x + 1, listofnumbers, listofnumbers)
5-element Array{Int64,1}:
 24
 46
 57
 68
 90

You could also create a separate destination object, like so


julia> listofnumbers = [23, 45, 56, 67, 89]
5-element Array{Int64,1}:
 23
 45
 56
 67
 89

julia> a = fill(0, 5)
5-element Array{Int64,1}:
 0
 0
 0
 0
 0

julia> map!(x -> x + 1, a, listofnumbers)
5-element Array{Int64,1}:
 24
 46
 57
 68
 90

julia> a
5-element Array{Int64,1}:
 24
 46
 57
 68
 90

Note that a = fill(0, 5) at the beginning and a = [24 46 57 68 90] at the end. This is because you were mutating a in-place.

3 Likes

:slight_smile:Thanks a lot! It works!
(… and I leaned more than one thing - with your help>? - it was new to me, too)

1 Like

Awesome, glad it worked!