@@ -33,6 +33,7 @@ class Operation
33
33
v [ 0 ] [ v [ 1 ] ..limit ]
34
34
end ,
35
35
'none' => -> ( v , d ) do
36
+
36
37
v [ 0 ] . each do |val |
37
38
this_val_satisfies_condition = interpolated_block ( v [ 1 ] , val )
38
39
if this_val_satisfies_condition
@@ -66,10 +67,9 @@ class Operation
66
67
return value if condition . truthy?
67
68
end
68
69
} ,
69
- '=' => -> ( v , d ) { v [ 0 ] . to_s . downcase == v [ 1 ] . to_s . downcase } ,
70
- '==' => -> ( v , d ) { v [ 0 ] . to_s . downcase == v [ 1 ] . to_s . downcase } ,
70
+ '==' => -> ( v , d ) { v [ 0 ] . to_s == v [ 1 ] . to_s } ,
71
71
'===' => -> ( v , d ) { v [ 0 ] == v [ 1 ] } ,
72
- '!=' => -> ( v , d ) { v [ 0 ] . to_s . downcase != v [ 1 ] . to_s . downcase } ,
72
+ '!=' => -> ( v , d ) { v [ 0 ] . to_s != v [ 1 ] . to_s } ,
73
73
'!==' => -> ( v , d ) { v [ 0 ] != v [ 1 ] } ,
74
74
'!' => -> ( v , d ) { v [ 0 ] . falsy? } ,
75
75
'!!' => -> ( v , d ) { v [ 0 ] . truthy? } ,
@@ -79,23 +79,20 @@ class Operation
79
79
result . nil? ? v . last : result
80
80
} ,
81
81
'?:' => -> ( v , d ) { LAMBDAS [ 'if' ] . call ( v , d ) } ,
82
- '>' => -> ( v , d ) { format_values ( v ) . each_cons ( 2 ) . all? { |i , j | i > j } } ,
83
- '>=' => -> ( v , d ) { format_values ( v ) . each_cons ( 2 ) . all? { |i , j | i >= j } } ,
84
- '<' => -> ( v , d ) { format_values ( v ) . each_cons ( 2 ) . all? { |i , j | i < j } } ,
85
- '<=' => -> ( v , d ) { format_values ( v ) . each_cons ( 2 ) . all? { |i , j | i <= j } } ,
86
- 'max' => -> ( v , d ) { format_values ( v ) . max } ,
87
- 'min' => -> ( v , d ) { format_values ( v ) . min } ,
82
+ '>' => -> ( v , d ) { v . map ( & :to_f ) . each_cons ( 2 ) . all? { |i , j | i > j } } ,
83
+ '>=' => -> ( v , d ) { v . map ( & :to_f ) . each_cons ( 2 ) . all? { |i , j | i >= j } } ,
84
+ '<' => -> ( v , d ) { v . map ( & :to_f ) . each_cons ( 2 ) . all? { |i , j | i < j } } ,
85
+ '<=' => -> ( v , d ) { v . map ( & :to_f ) . each_cons ( 2 ) . all? { |i , j | i <= j } } ,
86
+ 'max' => -> ( v , d ) { v . map ( & :to_f ) . max } ,
87
+ 'min' => -> ( v , d ) { v . map ( & :to_f ) . min } ,
88
88
'+' => -> ( v , d ) { v . map ( &:to_f ) . reduce ( :+ ) } ,
89
89
'-' => -> ( v , d ) { v . map! ( &:to_f ) ; v . size == 1 ? -v . first : v . reduce ( :- ) } ,
90
90
'*' => -> ( v , d ) { v . map ( &:to_f ) . reduce ( :* ) } ,
91
91
'/' => -> ( v , d ) { v . map ( &:to_f ) . reduce ( :/ ) } ,
92
92
'%' => -> ( v , d ) { v . map ( &:to_i ) . reduce ( :% ) } ,
93
93
'^' => -> ( v , d ) { v . map ( &:to_f ) . reduce ( :** ) } ,
94
94
'merge' => -> ( v , d ) { v . flatten } ,
95
- 'in' => -> ( v , d ) {
96
- v1_arg = interpolated_block ( v [ 1 ] , d )
97
- ( v1_arg . is_a? ( Array ) ? v1_arg . flatten : v1_arg ) . include? v [ 0 ]
98
- } ,
95
+ 'in' => -> ( v , d ) { interpolated_block ( v [ 1 ] , d ) . include? v [ 0 ] } ,
99
96
'cat' => -> ( v , d ) { v . map ( &:to_s ) . join } ,
100
97
'log' => -> ( v , d ) { puts v }
101
98
}
@@ -108,6 +105,7 @@ def self.interpolated_block(block, data)
108
105
def self . perform ( operator , values , data )
109
106
# If iterable, we can only pre-fill the first element, the second one must be evaluated per element.
110
107
# If not, we can prefill all.
108
+
111
109
if is_iterable? ( operator )
112
110
interpolated = [ JSONLogic . apply ( values [ 0 ] , data ) , *values [ 1 ..-1 ] ]
113
111
else
@@ -116,21 +114,8 @@ def self.perform(operator, values, data)
116
114
117
115
interpolated . flatten! ( 1 ) if interpolated . size == 1 # [['A']] => ['A']
118
116
119
- nil_vars = values . filter . with_index { |v , i | !JSONLogic . uses_data ( v ) . empty? && interpolated [ i ] . nil? }
120
- first_var_is_nil = !JSONLogic . uses_data ( values . first ) . empty? && interpolated . first . nil?
121
-
122
- if !is_standard? ( operator )
123
- send ( operator , interpolated , data )
124
- elsif is_nilable? ( operator ) && !nil_vars . empty?
125
- # short circuit and return nil
126
- nil
127
- elsif is_iterable? ( operator ) && first_var_is_nil
128
- # if an array variable resolves to nil, default to []
129
- interpolated [ 0 ] = [ ]
130
- LAMBDAS [ operator . to_s ] . call ( interpolated , data )
131
- else
132
- LAMBDAS [ operator . to_s ] . call ( interpolated , data )
133
- end
117
+ return LAMBDAS [ operator . to_s ] . call ( interpolated , data ) if is_standard? ( operator )
118
+ send ( operator , interpolated , data )
134
119
end
135
120
136
121
def self . is_standard? ( operator )
@@ -143,42 +128,10 @@ def self.is_iterable?(operator)
143
128
[ 'filter' , 'some' , 'all' , 'none' , 'in' , 'map' , 'reduce' ] . include? ( operator . to_s )
144
129
end
145
130
146
- def self . is_nilable? ( operator )
147
- [
148
- 'substr' ,
149
- '>' ,
150
- '>=' ,
151
- '<' ,
152
- '<=' ,
153
- 'max' ,
154
- 'min' ,
155
- '+' ,
156
- '-' ,
157
- '*' ,
158
- '/' ,
159
- '%' ,
160
- '^'
161
- ] . include? ( operator . to_s )
162
- end
163
-
164
131
def self . add_operation ( operator , function )
165
132
self . class . send ( :define_method , operator ) do |v , d |
166
133
function . call ( v , d )
167
134
end
168
135
end
169
-
170
- def self . format_values ( values )
171
- values = Array ( values ) . flatten
172
- # If at least 1 value is numeric, assume all values can be treated as such
173
- # Sometimes numbers are represented as strings, so they need to be converted
174
- if values . any? { |v | v . is_a? ( Numeric ) }
175
- values . map ( &:to_f )
176
- elsif values . all? { |v | v . is_a? ( String ) }
177
- values . map ( &:downcase )
178
- else
179
- # Convert everything to strings. This handles date comparison
180
- values . map ( &:to_s )
181
- end
182
- end
183
136
end
184
137
end
0 commit comments