@@ -183,6 +183,58 @@ class Functions {
183183 }
184184 }
185185
186+ /**
187+ * Get the item in the provided array that has the maximum value when the provided expression is evaluated.
188+ *
189+ * @param args The array of items to get the maximum value of
190+ * @param expression The expression to evaluate for each item in the array
191+ * @returns The item in the array that has the maximum value when the expression is evaluated
192+ */
193+ @Functions . signature ( {
194+ argumentsSpecs : [ [ 'array' ] , [ 'expression' ] ] ,
195+ } )
196+ public funcMaxBy (
197+ args : Array < JSONObject > ,
198+ expression : Expression
199+ ) : JSONObject | null {
200+ if ( args . length === 0 ) {
201+ return null ;
202+ }
203+
204+ const visitedArgs = args . map ( ( arg ) => ( {
205+ arg,
206+ visited : expression . visit ( arg ) ,
207+ } ) ) ;
208+
209+ const max = visitedArgs . reduce ( ( max , current ) => {
210+ const type = getType ( current . visited ) ;
211+ if ( type !== 'string' && type !== 'number' ) {
212+ throw new JMESPathTypeError ( {
213+ currentValue : current . visited ,
214+ expectedTypes : [ 'string' ] ,
215+ actualType : type ,
216+ } ) ;
217+ }
218+
219+ if (
220+ ( max . visited === null || max . visited === undefined ) &&
221+ ( current . visited === null || current . visited === undefined )
222+ ) {
223+ return max ;
224+ } else if ( max . visited === null || max . visited === undefined ) {
225+ return current ;
226+ } else if ( current . visited === null || current . visited === undefined ) {
227+ return max ;
228+ } else if ( max . visited === current . visited ) {
229+ return max ;
230+ } else {
231+ return max . visited > current . visited ? max : current ;
232+ }
233+ } , visitedArgs [ 0 ] ) ;
234+
235+ return max . arg ;
236+ }
237+
186238 /**
187239 * Merge the provided objects into a single object.
188240 *
@@ -219,6 +271,58 @@ class Functions {
219271 }
220272 }
221273
274+ /**
275+ * Get the item in the provided array that has the minimum value when the provided expression is evaluated.
276+ *
277+ * @param args The array of items to get the minimum value of
278+ * @param expression The expression to evaluate for each item in the array
279+ * @returns The item in the array that has the minimum value when the expression is evaluated
280+ */
281+ @Functions . signature ( {
282+ argumentsSpecs : [ [ 'array' ] , [ 'expression' ] ] ,
283+ } )
284+ public funcMinBy (
285+ args : Array < JSONObject > ,
286+ expression : Expression
287+ ) : JSONObject | null {
288+ if ( args . length === 0 ) {
289+ return null ;
290+ }
291+
292+ const visitedArgs = args . map ( ( arg ) => ( {
293+ arg,
294+ visited : expression . visit ( arg ) ,
295+ } ) ) ;
296+
297+ const min = visitedArgs . reduce ( ( min , current ) => {
298+ const type = getType ( current . visited ) ;
299+ if ( type !== 'string' && type !== 'number' ) {
300+ throw new JMESPathTypeError ( {
301+ currentValue : current . visited ,
302+ expectedTypes : [ 'string' ] ,
303+ actualType : type ,
304+ } ) ;
305+ }
306+
307+ if (
308+ ( min . visited === null || min . visited === undefined ) &&
309+ ( current . visited === null || current . visited === undefined )
310+ ) {
311+ return min ;
312+ } else if ( min . visited === null || min . visited === undefined ) {
313+ return current ;
314+ } else if ( current . visited === null || current . visited === undefined ) {
315+ return min ;
316+ } else if ( min . visited === current . visited ) {
317+ return min ;
318+ } else {
319+ return min . visited < current . visited ? min : current ;
320+ }
321+ } , visitedArgs [ 0 ] ) ;
322+
323+ return min . arg ;
324+ }
325+
222326 /**
223327 * Get the first argument that does not evaluate to null.
224328 * If all arguments evaluate to null, then null is returned.
0 commit comments