1
module NamedTupleUtilities
2

3
"""
4
    select(a::NamedTuple, v::Val{n})
5
Select a field `n` from `a` if it is in `a`.
6
```jldoctest
7
julia> QueryOperators.NamedTupleUtilities.select((a=1,b=2,c=3),Val(:a))
8
(a = 1,)
9
```
10
"""
11
@generated function select(a::NamedTuple{an}, ::Val{bn}) where {an, bn}
12 47
    names = ((i for i in an if i == bn)...,)
13 47
    types = Tuple{(fieldtype(a, n) for n in names)...}
14 47
    vals = Expr[:(getfield(a, $(QuoteNode(n)))) for n in names]
15 47
    return :(NamedTuple{$names,$types}(($(vals...),)))
16
end
17

18
"""
19
    remove(a::NamedTuple, v::Val{n})
20
Remove a field `n` from the `a` if it is in `a`.
21
```jldoctest
22
julia> QueryOperators.NamedTupleUtilities.remove((a=1,b=2,c=3),Val(:c))
23
(a = 1, b = 2)
24
```
25
"""
26
@generated function remove(a::NamedTuple{an}, ::Val{bn}) where {an, bn}
27 47
    names = ((i for i in an if i != bn)...,)
28 47
    types = Tuple{(fieldtype(a, n) for n in names)...}
29 47
    vals = Expr[:(getfield(a, $(QuoteNode(n)))) for n in names]
30 47
    return :(NamedTuple{$names,$types}(($(vals...),)))
31
end
32

33
"""
34
    range(a::NamedTuple, b::Val{n}, c::Val{n})
35
Return a NamedTuple which retains the fields from `b` to `c` in `a`. 
36
If `b` is not in `a`, then it will return the empty NamedTuple. 
37
If `c` is not in `a`, then it will return everything starting with `b`.
38
```jldoctest
39
julia> QueryOperators.NamedTupleUtilities.range((a=1,b=2,c=3),Val(:a),Val(:b))
40
(a = 1, b = 2)
41
```
42
"""
43
@generated function range(a::NamedTuple{an}, ::Val{bn}, ::Val{cn}) where {an, bn, cn}
44 47
    rangeStarted = false
45 39
    names = Symbol[]
46 47
    for n in an
47 47
        if n == bn
48
            rangeStarted = true
49
        end
50 47
        if rangeStarted
51 47
            push!(names, n)
52
        end
53 47
        if n == cn
54
            rangeStarted = false
55 47
            break
56
        end
57
    end
58 47
    types = Tuple{(fieldtype(a, n) for n in names)...}
59 47
    vals = Expr[:(getfield(a, $(QuoteNode(n)))) for n in names]
60 47
    return :( NamedTuple{$(names...,),$types}(($(vals...),)) )
61
end
62

63
"""
64
    rename(a::NamedTuple, b::Val{n}, c::Val{n})
65
Return a NamedTuple derived from `a` in which the the field from `b` is renamed to `c`. 
66
If `b` is not in `a`, then it will return the original NamedTuple. 
67
If `c` is in `a`, then `ERROR: duplicate field name in NamedTuple: "c" is not unique` will occur.
68
```jldoctest
69
julia> QueryOperators.NamedTupleUtilities.rename((a = 1, b = 2, c = 3),Val(:a),Val(:d))
70
(d = 1, b = 2, c = 3)
71
julia> QueryOperators.NamedTupleUtilities.rename((a = 1, b = 2, c = 3),Val(:m),Val(:d))
72
(a = 1, b = 2, c = 3)
73
julia> QueryOperators.NamedTupleUtilities.rename((a = 1, b = 2, c = 3),Val(:a),Val(:c))
74
ERROR: duplicate field name in NamedTuple: "c" is not unique
75
```
76
"""
77
@generated function rename(a::NamedTuple{an}, ::Val{bn}, ::Val{cn}) where {an, bn, cn}
78 47
    names = Symbol[]
79 39
    typesArray = DataType[]
80 39
    vals = Expr[]
81 47
    for n in an
82 47
        if n == bn
83 47
            push!(names, cn)
84
        else
85 47
            push!(names, n)
86
        end
87 47
        push!(typesArray, fieldtype(a, n))
88 47
        push!(vals, :(getfield(a, $(QuoteNode(n)))))
89
    end
90 47
    types = Tuple{typesArray...}
91 47
    return :(NamedTuple{$(names...,),$types}(($(vals...),)))
92
end
93

94
"""
95
    startswith(a::NamedTuple, b::Val{n})
96
Return a NamedTuple which retains the fields with names starting with `b` in `a`. 
97
```jldoctest
98
julia> QueryOperators.NamedTupleUtilities.startswith((abc=1,bcd=2,cde=3),Val(:a))
99
(abc = 1,)
100
```
101
"""
102
@generated function startswith(a::NamedTuple{an}, ::Val{bn}) where {an, bn}
103 47
    names = ((i for i in an if Base.startswith(String(i), String(bn)))...,)
104 47
    types = Tuple{(fieldtype(a, n) for n in names)...}
105 47
    vals = Expr[:(getfield(a, $(QuoteNode(n)))) for n in names]
106 47
    return :(NamedTuple{$names,$types}(($(vals...),)))
107
end
108

109
"""
110
    not_startswith(a::NamedTuple, b::Val{n})
111
Return a NamedTuple which retains the fields with names that do not start with `b` in `a`. 
112
```jldoctest
113
julia> QueryOperators.NamedTupleUtilities.not_startswith((abc=1,bcd=2,cde=3),Val(:a))
114
(bcd = 2, cde = 3)
115
```
116
"""
117
@generated function not_startswith(a::NamedTuple{an}, ::Val{bn}) where {an, bn}
118 47
    names = ((i for i in an if !Base.startswith(String(i), String(bn)))...,)
119 47
    types = Tuple{(fieldtype(a, n) for n in names)...}
120 47
    vals = Expr[:(getfield(a, $(QuoteNode(n)))) for n in names]
121 47
    return :(NamedTuple{$names,$types}(($(vals...),)))
122
end
123

124
"""
125
    endswith(a::NamedTuple, b::Val{n})
126
Return a NamedTuple which retains the fields with names that do not end with `b` in `a`. 
127
```jldoctest
128
julia> QueryOperators.NamedTupleUtilities.not_endswith((abc=1,bcd=2,cde=3),Val(:d))
129
(abc = 1, cde = 3)
130
```
131
"""
132
@generated function endswith(a::NamedTuple{an}, ::Val{bn}) where {an, bn}
133 47
    names = ((i for i in an if Base.endswith(String(i), String(bn)))...,)
134 47
    types = Tuple{(fieldtype(a, n) for n in names)...}
135 47
    vals = Expr[:(getfield(a, $(QuoteNode(n)))) for n in names]
136 47
    return :(NamedTuple{$names,$types}(($(vals...),)))
137
end
138

139
"""
140
    not_endswith(a::NamedTuple, b::Val{n})
141
Return a NamedTuple which retains the fields with names ending with `b` in `a`. 
142
```jldoctest
143
julia> QueryOperators.NamedTupleUtilities.endswith((abc=1,bcd=2,cde=3),Val(:d))
144
(bcd = 2,)
145
```
146
"""
147
@generated function not_endswith(a::NamedTuple{an}, ::Val{bn}) where {an, bn}
148 47
    names = ((i for i in an if !Base.endswith(String(i), String(bn)))...,)
149 47
    types = Tuple{(fieldtype(a, n) for n in names)...}
150 47
    vals = Expr[:(getfield(a, $(QuoteNode(n)))) for n in names]
151 47
    return :(NamedTuple{$names,$types}(($(vals...),)))
152
end
153

154
"""
155
    occursin(a::NamedTuple, b::Val{n})
156
Return a NamedTuple which retains the fields with names containing `b` as a substring. 
157
```jldoctest
158
julia> QueryOperators.NamedTupleUtilities.occursin((abc=1,bcd=2,cde=3),Val(:d))
159
(bcd = 2, cde = 3)
160
```
161
"""
162
@generated function occursin(a::NamedTuple{an}, ::Val{bn}) where {an, bn}
163 47
    names = ((i for i in an if Base.occursin(String(bn), String(i)))...,)
164 47
    types = Tuple{(fieldtype(a, n) for n in names)...}
165 47
    vals = Expr[:(getfield(a, $(QuoteNode(n)))) for n in names]
166 47
    return :(NamedTuple{$names,$types}(($(vals...),)))
167
end
168

169
"""
170
    not_occursin(a::NamedTuple, b::Val{n})
171
Return a NamedTuple which retains the fields without names containing `b` as a substring. 
172
```jldoctest
173
julia> QueryOperators.NamedTupleUtilities.not_occursin((abc=1,bcd=2,cde=3),Val(:d))
174
(abc = 1,)
175
```
176
"""
177
@generated function not_occursin(a::NamedTuple{an}, ::Val{bn}) where {an, bn}
178 47
    names = ((i for i in an if !Base.occursin(String(bn), String(i)))...,)
179 47
    types = Tuple{(fieldtype(a, n) for n in names)...}
180 47
    vals = Expr[:(getfield(a, $(QuoteNode(n)))) for n in names]
181 47
    return :(NamedTuple{$names,$types}(($(vals...),)))
182
end
183

184
"""
185
    oftype(a::NamedTuple, b::DataType)
186
Returns a NamedTuple which retains the fields whose elements have type `b`.
187
```jldoctest
188
julia> QueryOperators.NamedTupleUtilities.oftype((a = [4,5,6], b = [3.,2.,1.], c = ["He","llo","World!"]), Val(Int64))
189
(a = [4, 5, 6],)
190
julia> QueryOperators.NamedTupleUtilities.oftype((a = [4,5,6], b = [3.,2.,1.], c = ["He","llo","World!"]), Val(Number))
191
(a = [4, 5, 6], b = [3., 2., 1.])
192
julia> QueryOperators.NamedTupleUtilities.oftype((a = [4,5,6], b = [3.,2.,1.], c = ["He","llo","World!"]), Val(Float32))
193
NamedTuple()
194
```
195
"""
196
@generated function oftype(a::NamedTuple{an}, ::Val{b}) where {an, b}
197 47
    names = ((i for i in an if fieldtype(a, i) <: b)...,)
198 47
    types = Tuple{(fieldtype(a, n) for n in names)...}
199 47
    vals = Expr[:(getfield(a, $(QuoteNode(n)))) for n in names]
200 47
    return :(NamedTuple{$names,$types}(($(vals...),)))
201
end
202

203
end

Read our documentation on viewing source code .

Loading