diff --git a/Languages/Ruby/Libraries/Builtins/Enumerable.cs b/Languages/Ruby/Libraries/Builtins/Enumerable.cs index 9ae3cd181a..2062b8af4a 100644 --- a/Languages/Ruby/Libraries/Builtins/Enumerable.cs +++ b/Languages/Ruby/Libraries/Builtins/Enumerable.cs @@ -588,6 +588,46 @@ public static class Enumerable { #endregion #region TODO: min_by, max_by, minmax_by + + [RubyMethod("min_by")] + public static object GetMinBy(CallSiteStorage/*!*/ each, ComparisonStorage/*!*/ comparisonStorage, BlockParam comparer, object self) { + + bool firstItem = true; + object result = null; + object resultValue = null; + + Each(each, self, Proc.Create(each.Context, delegate(BlockParam/*!*/ selfBlock, object _, object item) { + if (firstItem) { + result = item; + object firstBlockResult; + comparer.Yield(item, out blockResult); + resultValue = blockResult; + firstItem = false; + return null; + } + + Protocols.Compare(comparisonStorage, left, right); + + object itemBlockResult; + comparer.Yield (item, out itemBlockResult); + object compareBlockResult; + int? compareResult = CompareItems(comparisonStorage, itemBlockResult, resultValue, comparer, out compareBlockResult); + if (compareResult == null) { + result = compareBlockResult; + return selfBlock.PropagateFlow(comparer, blockResult); + } + + // Check if we have found the new minimum or maximum (+1 to select max, -1 to select min) + if (compareResult == comparisonValue) { + result = item; + resultValue = itemBlockResult; + } + + return null; + })); + + return result; + } #endregion