@@ -18,7 +18,7 @@ class Operation
18
18
end
19
19
end ,
20
20
'missing' => -> ( v , d ) do
21
- v . select do |val |
21
+ v . flatten . select do |val |
22
22
keys = VarCache . fetch_or_store ( val )
23
23
d . deep_fetch ( keys ) . nil?
24
24
end
@@ -30,15 +30,15 @@ class Operation
30
30
'some' => -> ( v , d ) do
31
31
return false unless v [ 0 ] . is_a? ( Array )
32
32
33
- v [ 0 ] . any? do |val |
34
- interpolated_block ( v [ 1 ] , val ) . truthy?
33
+ v [ 1 ] . any? do |item |
34
+ item . truthy?
35
35
end
36
36
end ,
37
37
'filter' => -> ( v , d ) do
38
38
return [ ] unless v [ 0 ] . is_a? ( Array )
39
39
40
- v [ 0 ] . select do |val |
41
- interpolated_block ( v [ 1 ] , val ) . truthy?
40
+ v [ 0 ] . select . with_index do |_ , index |
41
+ v [ 1 ] [ index ] . truthy?
42
42
end
43
43
end ,
44
44
'substr' => -> ( v , d ) do
@@ -54,33 +54,28 @@ class Operation
54
54
v [ 0 ] [ v [ 1 ] ..limit ]
55
55
end ,
56
56
'none' => -> ( v , d ) do
57
+ return false unless v [ 0 ] . is_a? ( Array )
57
58
58
- v [ 0 ] . each do |val |
59
- this_val_satisfies_condition = interpolated_block ( v [ 1 ] , val )
60
- if this_val_satisfies_condition
61
- return false
62
- end
59
+ v [ 1 ] . all? do |item |
60
+ item . falsy?
63
61
end
64
-
65
- return true
66
62
end ,
67
63
'all' => -> ( v , d ) do
64
+ return false unless v [ 0 ] . is_a? ( Array )
68
65
# Difference between Ruby and JSONLogic spec ruby all? with empty array is true
69
66
return false if v [ 0 ] . empty?
70
67
71
- v [ 0 ] . all? do |val |
72
- interpolated_block ( v [ 1 ] , val )
68
+ v [ 1 ] . all? do |item |
69
+ item . truthy?
73
70
end
74
71
end ,
75
72
'reduce' => -> ( v , d ) do
76
73
return v [ 2 ] unless v [ 0 ] . is_a? ( Array )
77
- v [ 0 ] . inject ( v [ 2 ] ) { |acc , val | interpolated_block ( v [ 1 ] , { "current" : val , "accumulator" : acc } ) }
74
+ v [ 0 ] . inject ( v [ 2 ] ) { |acc , val | v [ 1 ] . evaluate ( { "current" => val , "accumulator" => acc } ) }
78
75
end ,
79
76
'map' => -> ( v , d ) do
80
77
return [ ] unless v [ 0 ] . is_a? ( Array )
81
- v [ 0 ] . map do |val |
82
- interpolated_block ( v [ 1 ] , val )
83
- end
78
+ v [ 1 ]
84
79
end ,
85
80
'if' => -> ( v , d ) {
86
81
v . each_slice ( 2 ) do |condition , value |
@@ -115,42 +110,23 @@ class Operation
115
110
'%' => -> ( v , d ) { v . map ( &:to_i ) . reduce ( :% ) } ,
116
111
'^' => -> ( v , d ) { v . map ( &:to_f ) . reduce ( :** ) } ,
117
112
'merge' => -> ( v , d ) { v . flatten } ,
118
- 'in' => -> ( v , d ) { interpolated_block ( v [ 1 ] , d ) . include? v [ 0 ] } ,
113
+ 'in' => -> ( v , d ) { v [ 1 ] . include? ( v [ 0 ] ) } ,
119
114
'cat' => -> ( v , d ) { v . map ( &:to_s ) . join } ,
120
115
'log' => -> ( v , d ) { puts v }
121
116
}
122
117
123
- def self . interpolated_block ( block , data )
124
- # Make sure the empty var is there to be used in iterator
125
- JSONLogic . apply ( block , data . is_a? ( Hash ) ? data . merge ( { "" : data } ) : { "" : data } )
126
- end
127
-
128
118
def self . perform ( operator , values , data )
129
- # If iterable, we can only pre-fill the first element, the second one must be evaluated per element.
130
- # If not, we can prefill all.
131
-
132
- if is_iterable? ( operator )
133
- interpolated = [ JSONLogic . apply ( values [ 0 ] , data ) , *values [ 1 ..-1 ] ]
119
+ if is_standard? ( operator )
120
+ LAMBDAS [ operator . to_s ] . call ( values , data )
134
121
else
135
- interpolated = values . map { | val | JSONLogic . apply ( val , data ) }
122
+ send ( operator , values , data )
136
123
end
137
-
138
- interpolated . flatten! ( 1 ) if interpolated . size == 1 # [['A']] => ['A']
139
-
140
- return LAMBDAS [ operator . to_s ] . call ( interpolated , data ) if is_standard? ( operator )
141
- send ( operator , interpolated , data )
142
124
end
143
125
144
126
def self . is_standard? ( operator )
145
127
LAMBDAS . key? ( operator . to_s )
146
128
end
147
129
148
- # Determine if values associated with operator need to be re-interpreted for each iteration(ie some kind of iterator)
149
- # or if values can just be evaluated before passing in.
150
- def self . is_iterable? ( operator )
151
- [ 'filter' , 'some' , 'all' , 'none' , 'in' , 'map' , 'reduce' ] . include? ( operator . to_s )
152
- end
153
-
154
130
def self . add_operation ( operator , function )
155
131
self . class . send ( :define_method , operator ) do |v , d |
156
132
function . call ( v , d )
0 commit comments