using NamedTupleTools: namedtuple, select
# no inline, no splat (version in NamedTupleTools at time of writing)
select_00(nt::NamedTuple, ks) = namedtuple(ks)(((nt[k] for k in ks)...,))
# inline, no splat
@inline select_10(nt::NamedTuple, ks) = namedtuple(ks)(((nt[k] for k in ks)...,))
# no inline, splat
select_01(nt::NamedTuple, ks) = namedtuple(ks)(map(k->nt[k], ks))
# inline, no splat
@inline select_11(nt::NamedTuple, ks) = namedtuple(ks)(map(k->nt[k], ks))
test_select_hc(t) = (b=t.b, a=t.a) # hard-coded
test_select_00(t) = select_00(t, (:b, :a))
test_select_01(t) = select_01(t, (:b, :a))
test_select_10(t) = select_10(t, (:b, :a))
test_select_11(t) = select_11(t, (:b, :a))
# @code_llvm test_select_ntt((a=3,b=4,c=5))
using Test: Test
macro testinferred(ex)
quote
try
Test.@inferred $ex
nothing
catch e
e
end
end
end
@show @testinferred test_select_00((a=3,b=4,c=5))
@show @testinferred test_select_01((a=3,b=4,c=5))
@show @testinferred test_select_10((a=3,b=4,c=5))
@show @testinferred test_select_11((a=3,b=4,c=5))
produces
@testinferred(test_select_00((a = 3, b = 4, c = 5))) = ErrorException("return type NamedTuple{(:b, :a),Tuple{Int64,Int64}} does not match inferred return type NamedTuple")
@testinferred(test_select_01((a = 3, b = 4, c = 5))) = ErrorException("return type NamedTuple{(:b, :a),Tuple{Int64,Int64}} does not match inferred return type NamedTuple{_A,Tuple{Int64,Int64}} where _A")
@testinferred(test_select_10((a = 3, b = 4, c = 5))) = ErrorException("return type NamedTuple{(:b, :a),Tuple{Int64,Int64}} does not match inferred return type NamedTuple{(:b, :a),_A} where _A<:Tuple")
@testinferred(test_select_11((a = 3, b = 4, c = 5))) = nothing
Here is one example using
NamedTupleTools.select
produces