# Right way to transform keyword arguments

**URL:** <https://discourse.julialang.org/t/right-way-to-transform-keyword-arguments/14057>\
**Category:** General Usage\
**Created:** [August 25, 2018, 8:55pm UTC](https://discourse.julialang.org/t/right-way-to-transform-keyword-arguments/14057 "2018-08-25T20:55:49Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![denizyuret](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/denizyuret/32/568_2.png) [@denizyuret](https://discourse.julialang.org/u/denizyuret)\
**Post date:** [August 25, 2018, 8:55pm UTC](https://discourse.julialang.org/t/right-way-to-transform-keyword-arguments/14057/1 "2018-08-25T20:55:49Z")

</div>

If `f(xf...;of...)` is going to call `g(xg...; og...)` after applying some transformations `xf->xg` and `of->og`, what is the most efficient way to do this? `of` happens to be a `pairs` iterator of `NamedTuples`, so direct `map` on it doesn’t work. Here is what I managed but I don’t think it is portable:

```julia
function f(xf...; of...)
    xg = map(transform,xf)
    og = pairs(map(transform,of.data))
    g(xg...; og...)
end

```

---

<div class="post-metadata">

**Author:** ![piever](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/piever/32/1815_2.png) [@piever](https://discourse.julialang.org/u/piever)\
**Post date:** [August 25, 2018, 9:03pm UTC](https://discourse.julialang.org/t/right-way-to-transform-keyword-arguments/14057/2 "2018-08-25T21:03:04Z")

</div>

Not sure if this is useful but I think you can also splat the `NamedTuple` as keyword arguments:

```julia
julia> f(; a=1, b=2) = a-b
f (generic function with 1 method)

julia> f(; (b=10, a=20)...)
10

```

Is `of.data` is the recommended way to convert the iterator to `NamedTuple`? Maybe there should be some exported accessor function.

---

<div class="post-metadata">

**Author:** ![saschatimme](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/saschatimme/32/10313_2.png) [@saschatimme](https://discourse.julialang.org/u/saschatimme)\
**Post date:** [August 25, 2018, 10:48pm UTC](https://discourse.julialang.org/t/right-way-to-transform-keyword-arguments/14057/3 "2018-08-25T22:48:45Z")

</div>

How would it be with

```julia
function f(xf...; of...)
    xg = map(transform,xf)
    og = (transform(o) for in pairs(o))
    g(xg...; og...)
end

```

Here `(transform(o) for in pairs(o))` is a chain of two iterators which then gets splatted again, so this should theoretically be not bad.

---

<div class="post-metadata">

**Author:** ![dawbarton](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dawbarton/32/215461_2.png) [@dawbarton](https://discourse.julialang.org/u/dawbarton)\
**Post date:** [August 25, 2018, 11:12pm UTC](https://discourse.julialang.org/t/right-way-to-transform-keyword-arguments/14057/4 "2018-08-25T23:12:51Z")

</div>

`values(of)` appears to give the underlying named tuple (like `of.data`), so you could use that to make it portable.

```julia
function f(xf...; of...)
    xg = map(transform,xf)
    og = pairs(map(transform,values(of)))
    g(xg...; og...)
end

```

In terms of efficiency, I tried with generator expressions but your map version was better by a long way.

(For reference -

```julia
function f2(xf...; of...)
    xg = map(transform,xf)
    og = (key => transform(value) for (key, value) in of)
    g(xg...; og...)
end

```

it wasn’t very efficient.)

---

<div class="post-metadata">

**Author:** ![denizyuret](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/denizyuret/32/568_2.png) [@denizyuret](https://discourse.julialang.org/u/denizyuret)\
**Post date:** [August 27, 2018, 8:46pm UTC](https://discourse.julialang.org/t/right-way-to-transform-keyword-arguments/14057/5 "2018-08-27T20:46:25Z")

</div>

Thanks for all the responses. Here is a benchmark comparing different suggestions:

```julia
julia> @benchmark og = (x[1]=>sum(x[2]) for x in of)
  minimum time: 71.074 ns (0.00% GC)
julia> @benchmark collect(x[1]=>sum(x[2]) for x in of) # note that this gives an array
  minimum time: 260.378 ns (0.00% GC)
julia> @benchmark og = pairs(map(sum, values(of)))
  minimum time: 118.039 ns (0.00% GC)
julia> @benchmark og = collect(map(sum, values(of)))
  minimum time: 130.588 ns (0.00% GC)
```
