@@ -112,26 +112,29 @@ mod inner {
112112 }
113113 }
114114 pub fn max_by_key ( seq : & mut Sequence , func : & Callable < ' _ > ) -> EvaluationResult {
115- let mut best_value = None ;
116- let mut best_key = None ;
117-
118- for value in mut_seq_to_iterator ( seq) {
119- if let Some ( best_key_val) = & best_key {
120- let new_key = func. call ( & mut [ value. clone ( ) ] ) ?;
121- if & new_key > best_key_val {
122- best_key = Some ( new_key) ;
123- best_value = Some ( value) ;
124- }
125- } else {
126- best_key = Some ( func. call ( & mut [ value. clone ( ) ] ) ?) ;
127- best_value = Some ( value) ;
128- }
129- }
115+ by_key ( seq, func, Ordering :: Greater )
116+ }
130117
131- match best_value {
132- None => Err ( anyhow:: anyhow!( "empty input to max_by_key" ) ) ?,
133- Some ( value) => Ok ( value) ,
134- }
118+ pub fn min_by_key ( seq : & mut Sequence , func : & Callable < ' _ > ) -> EvaluationResult {
119+ by_key ( seq, func, Ordering :: Less )
120+ }
121+
122+ /// Returns the maximum element using a comparator function.
123+ ///
124+ /// The comparator function takes two elements and returns a number. A positive result means the
125+ /// first argument is greater than the second, a negative result means the first argument is
126+ /// less than the second, and zero means they are equal.
127+ pub fn max_by ( seq : & mut Sequence , comp : & Callable < ' _ > ) -> EvaluationResult {
128+ by_comp ( seq, comp, Ordering :: Greater )
129+ }
130+
131+ /// Returns the minimum element using a comparator function.
132+ ///
133+ /// The comparator function takes two elements and returns a number. A positive result means the
134+ /// first argument is greater than the second, a negative result means the first argument is
135+ /// less than the second, and zero means they are equal.
136+ pub fn min_by ( seq : & mut Sequence , comp : & Callable < ' _ > ) -> EvaluationResult {
137+ by_comp ( seq, comp, Ordering :: Less )
135138 }
136139
137140 /// Returns the lowest element in the sequence.
@@ -772,6 +775,52 @@ mod inner {
772775 }
773776}
774777
778+ fn by_key (
779+ seq : & mut Sequence ,
780+ func : & Callable < ' _ > ,
781+ better : Ordering ,
782+ ) -> EvaluationResult {
783+ let mut best_value = None ;
784+ let mut best_key: Option < Value > = None ;
785+
786+ for value in mut_seq_to_iterator ( seq) {
787+ let new_key = func. call ( & mut [ value. clone ( ) ] ) ?;
788+ let is_better = match & best_key {
789+ None => true ,
790+ Some ( current_best) => new_key. try_cmp ( current_best) ? == better,
791+ } ;
792+ if is_better {
793+ best_key = Some ( new_key) ;
794+ best_value = Some ( value) ;
795+ }
796+ }
797+
798+ best_value. ok_or_else ( || anyhow:: anyhow!( "sequence was empty" ) . into ( ) )
799+ }
800+
801+ fn by_comp (
802+ seq : & mut Sequence ,
803+ comp : & Callable < ' _ > ,
804+ better : Ordering ,
805+ ) -> EvaluationResult {
806+ let mut best: Option < Value > = None ;
807+
808+ for value in mut_seq_to_iterator ( seq) {
809+ let is_better = match & best {
810+ None => true ,
811+ Some ( current) => {
812+ let result = comp. call ( & mut [ value. clone ( ) , current. clone ( ) ] ) ?;
813+ result. try_cmp ( & Value :: from ( 0 ) ) ? == better
814+ }
815+ } ;
816+ if is_better {
817+ best = Some ( value) ;
818+ }
819+ }
820+
821+ best. ok_or_else ( || anyhow:: anyhow!( "sequence was empty" ) . into ( ) )
822+ }
823+
775824fn fold_iterator (
776825 iterator : MutableValueIntoIterator < ' _ > ,
777826 initial : Value ,
0 commit comments