Do-block for combining structures

question

#1

Trying to find an example for the do-block syntax a I came to the following code: the anonymous function/closure in the do-block combines input arguments into a resulting structure. Is the code below correct as an example for this concept? Are there any cons/restrictions for using the do-block syntax (except the scope of variables inside the do-block); for example capturing the variables inside the do-block?

struct Foo
  name::String
  data::Vector{Float64}
end

struct Baz
  name::String
  info::Int
end

struct Bar
  name::String
  info::Int
  data::Vector{Vector{Float64}}
end

function combine(inFoo::Vector{Foo}, inBaz::Vector{Baz})
  names = unique([a.name for a in inFoo])
  bars = map(names) do a
    blocks = [ b.data for b in inFoo if b.name == a ]
    i = findfirst(r -> r.name == a, inBaz)
    info = i !=0 ? bazs[i].info : 0
    return Bar(a, info, blocks)
  end

  return bars
end

foos = [Foo("a", [1.0, 2.0]), Foo("a",[6.0]), Foo("b", [21.0, 22.0]), Foo("b", [25.0])]
bazs = [Baz("a", 10), Baz("b", 11)]
combine(foos, bazs)

#2

If it does what you want, equivalently to map(a -> ..., names), then yes.

About “capturing the variable”: if name wasn’t string but a mutable container that may be modified, then you would get tricky behavior, but that is orthogonal to do syntax and isn’t the case here anyway.


#3

thanks for pointing out the mutable container, though it is not the case here.