How to repeat the format in @printf?

Yes, but that generates strings. format can operate on an IO, so it wouldn’t be too hard to define such a function that doesn’t go via strings at all.

1 Like

You are right. For avoiding even the intermediate strings, something like

function join2(io, f, itr, delim, last = delim)
    for (i, a) in enumerate(a)
        i == 0 || print(io, delim)
        f(io, a)
    end
    print(io, last)
end

which takes a two-argument function but encapsulates the logic of join would be nice.

2 Likes

Swap the first two arguments and you can do

delimiter="\t"
numbers=randn(20)
fmt=Format("%.2f")
open("file.tsv", "w") do file
    join(file, numbers, delimiter) do io, x
        format(io, fmt, x)
    end
end

Not sure why you’d want to, but it looks pretty cool.

1 Like

You can use the splat operator.

Printf.format(io, f, a...)
1 Like

I’m confused about this one. When I tried it I got

julia> x=rand(3);

julia> fmt=Printf.Format("%.2f");

julia> Printf.format(fmt,x...)
ERROR: ArgumentError: mismatch between # of format specifiers and provided args: 1 != 3

What have I missed?

Your format string only has one specifier, so it will only work on one argument. Depending on what output you’re expecting, there’s options like

julia> fmt=Printf.Format("%.2f"^3); # equivalent to "%.2f%.2f%.2f"

julia> Printf.format(fmt, x...)
"0.030.050.21"

or

julia> fmt=Printf.Format("%.2f");

julia> Printf.format.(Ref(fmt),x)
3-element Vector{String}:
"0.03"
"0.05"
"0.21"
1 Like

Especially the three dots at the end (splat operator) help a lot :slight_smile:

For the record, probably the best solution here is just write a double loop: Writing array to file with format - #2 by stevengj

julia> using Printf

julia> A = rand(3,3);

julia> # with io == stdout
       for i in axes(A,1)
           for j in axes(A,2)
               @printf(" %5.2f", A[i,j])
           end
           println() # new line
       end
  0.21  0.48  0.26
  0.12  0.92  0.17
  0.03  0.91  0.41

or to a file:

julia> open("test.txt","w") do io
           for i in axes(A,1)
               for j in axes(A,2)
                   @printf(io, " %5.2f", A[i,j])
               end
               println(io) # new line
           end
       end

shell> more test.txt
  0.21  0.48  0.26
  0.12  0.92  0.17
  0.03  0.91  0.41
2 Likes