diff --git a/Configuration/GlobalAssemblyInfo.cs b/Configuration/GlobalAssemblyInfo.cs index 35babc725..623c38964 100644 --- a/Configuration/GlobalAssemblyInfo.cs +++ b/Configuration/GlobalAssemblyInfo.cs @@ -15,7 +15,7 @@ internal static class RevisionClass public const string Major = "3"; public const string Minor = "10"; public const string Build = "0"; - public const string Revision = "3546"; + public const string Revision = "3547"; public const string MainVersion = Major + "." + Minor; public const string FullVersion = Major + "." + Minor + "." + Build + "." + Revision; diff --git a/Configuration/Version.defs b/Configuration/Version.defs index 787d2479c..829ea7b9b 100644 --- a/Configuration/Version.defs +++ b/Configuration/Version.defs @@ -1,4 +1,4 @@ -%COREVERSION%=0 -%REVISION%=3546 %MINOR%=10 +%REVISION%=3547 +%COREVERSION%=0 %MAJOR%=3 diff --git a/Release/pabcversion.txt b/Release/pabcversion.txt index f73410b6e..dc60009d0 100644 --- a/Release/pabcversion.txt +++ b/Release/pabcversion.txt @@ -1 +1 @@ -3.10.0.3546 +3.10.0.3547 diff --git a/ReleaseGenerators/PascalABCNET_version.nsh b/ReleaseGenerators/PascalABCNET_version.nsh index a6aed0991..1dea5948e 100644 --- a/ReleaseGenerators/PascalABCNET_version.nsh +++ b/ReleaseGenerators/PascalABCNET_version.nsh @@ -1 +1 @@ -!define VERSION '3.10.0.3546' +!define VERSION '3.10.0.3547' diff --git a/TestSuite/CompilationSamples/Coords.pas b/TestSuite/CompilationSamples/Coords.pas index 0a44fe5a1..5bfa0ab4f 100644 --- a/TestSuite/CompilationSamples/Coords.pas +++ b/TestSuite/CompilationSamples/Coords.pas @@ -635,6 +635,12 @@ type Redraw; end; + static procedure KeyPress(c: char); + begin + if c.ToLower = 's' then + Window.SaveToClipboard; + end; + static procedure Resize; begin Redraw; @@ -647,8 +653,9 @@ initialization Window.Title := 'Система координат'; finalization Redraw; - OnMouseWheel := Handlers.MouseWheel; - OnMouseDown := Handlers.MouseDown; - OnMouseMove := Handlers.MouseMove; - OnResize := Handlers.Resize; + OnMouseWheel += Handlers.MouseWheel; + OnMouseDown += Handlers.MouseDown; + OnMouseMove += Handlers.MouseMove; + OnResize += Handlers.Resize; + OnKeyPress += Handlers.KeyPress; end. \ No newline at end of file diff --git a/TestSuite/CompilationSamples/GraphWPF.pas b/TestSuite/CompilationSamples/GraphWPF.pas index eb02664ae..e423dca79 100644 --- a/TestSuite/CompilationSamples/GraphWPF.pas +++ b/TestSuite/CompilationSamples/GraphWPF.pas @@ -230,6 +230,8 @@ type function Center: Point; /// Сохраняет содержимое графического окна в файл с именем fname procedure Save(fname: string); + /// Сохраняет содержимое графического окна в буфер обмена + procedure SaveToClipboard; /// Восстанавливает содержимое графического окна из файла с именем fname procedure Load(fname: string); /// Заполняет содержимое графического окна обоями из файла с именем fname @@ -249,6 +251,8 @@ type public /// Сохраняет содержимое графического окна в файл с именем fname procedure Save(fname: string); + /// Сохраняет содержимое графического окна в буфер обмена + procedure SaveToClipboard; /// Восстанавливает содержимое графического окна из файла с именем fname procedure Load(fname: string); /// Очищает графическое окно белым цветом @@ -2005,7 +2009,7 @@ begin end; function GraphWindowType.GetHeight := InvokeReal(GraphWindowTypeGetHeightP); -procedure SaveWindowP(canvas: FrameworkElement; filename: string); +function SaveWindowToBitmapP(canvas: FrameworkElement): BitmapSource; begin HostToRenderBitmap; var (scalex,scaley) := ScaleToDevice; @@ -2042,6 +2046,19 @@ begin bmp.Render(canvas); + Result := bmp; +end; + +procedure SaveWindowToClipboardP(canvas: FrameworkElement); +begin + var bmp := SaveWindowToBitmapP(canvas); + Clipboard.SetImage(bmp) +end; + +procedure SaveWindowP(canvas: FrameworkElement; filename: string); +begin + var bmp := SaveWindowToBitmapP(canvas); + dpic[filename] := bmp; (canvas as MyVisualHost).children.RemoveAt(0); @@ -2066,6 +2083,8 @@ end; procedure GraphWindowType.Save(fname: string) := Invoke(SaveWindowP,host,fname); +procedure GraphWindowType.SaveToClipboard := Invoke(SaveWindowToClipboardP,host); + procedure GraphWindowType.Load(fname: string) := DrawImageUnscaled(0,0,fname); procedure GraphWindowType.Fill(fname: string); @@ -2088,6 +2107,8 @@ function GraphWindowType.ClientRect: GRect := Rect(0,0,Width,Height); procedure WindowTypeWPF.Save(fname: string) := GraphWindow.Save(fname); +procedure WindowTypeWPF.SaveToClipboard := GraphWindow.SaveToClipboard; + procedure WindowTypeWPF.Load(fname: string) := GraphWindow.Load(fname); procedure WindowTypeClearP; diff --git a/TestSuite/CompilationSamples/PABCSystem.pas b/TestSuite/CompilationSamples/PABCSystem.pas index 402cf81f5..308a1be83 100644 --- a/TestSuite/CompilationSamples/PABCSystem.pas +++ b/TestSuite/CompilationSamples/PABCSystem.pas @@ -3013,6 +3013,8 @@ const Format_InvalidString = 'Входная строка имела неверный формат!!Input string was not in a correct format'; Overflow_Int32 = 'Целочисленное переполнение!!Integer overflow'; FOR_STEP_CANNOT_BE_EQUAL0 = 'Шаг цикла for не может быт равен 0!!Step of the for loop cannot be equal to 0'; + SEQUENCE_CANNOT_BE_EMPTY = 'Последовательность не может быть пустой!!Sequence cannot be empty'; + ARRAY_CANNOT_BE_EMPTY = 'Массив не может быть пустым!!Array cannot be empty'; // ----------------------------------------------------- // WINAPI // ----------------------------------------------------- @@ -11007,43 +11009,103 @@ end; // Дополнения 2024: Zip - синоним ZipTuple /// Возвращает первый элемент последовательности с минимальным значением ключа -function MinBy(Self: sequence of T; selector: T->TKey): T; extensionmethod; +function MinBy(Self: sequence of T; keySelector: T -> TKey): T; extensionmethod; begin - if selector = nil then - raise new ArgumentNullException('selector'); + var enumerator := Self.GetEnumerator(); + if not enumerator.MoveNext() then + raise new System.ArgumentException(GetTranslation(SEQUENCE_CANNOT_BE_EMPTY)); + var minElement := enumerator.Current; + var minKey := keySelector(minElement); + var comp := Comparer&.Default; - Result := Self.Aggregate((min, x)-> comp.Compare(selector(x), selector(min)) < 0 ? x : min); + while enumerator.MoveNext() do + begin + var currentElement := enumerator.Current; + var currentKey := keySelector(currentElement); + if comp.Compare(currentKey,minKey) < 0 then + begin + minKey := currentKey; + minElement := currentElement; + end; + end; + + Result := minElement; end; /// Возвращает первый элемент последовательности с максимальным значением ключа -function MaxBy(Self: sequence of T; selector: T->TKey): T; extensionmethod; +function MaxBy(Self: sequence of T; keySelector: T -> TKey): T; extensionmethod; begin - if selector = nil then - raise new ArgumentNullException('selector'); + var enumerator := Self.GetEnumerator(); + if not enumerator.MoveNext() then + raise new System.ArgumentException(GetTranslation(SEQUENCE_CANNOT_BE_EMPTY)); + var maxElement := enumerator.Current; + var maxKey := keySelector(maxElement); + var comp := Comparer&.Default; - Result := Self.Aggregate((max, x)-> comp.Compare(selector(x), selector(max)) > 0 ? x : max); + while enumerator.MoveNext() do + begin + var currentElement := enumerator.Current; + var currentKey := keySelector(currentElement); + if comp.Compare(currentKey,maxKey) > 0 then + begin + maxKey := currentKey; + maxElement := currentElement; + end; + end; + + Result := maxElement; end; /// Возвращает последний элемент последовательности с минимальным значением ключа -function LastMinBy(Self: sequence of T; selector: T->TKey): T; extensionmethod; +function LastMinBy(Self: sequence of T; keySelector: T -> TKey): T; extensionmethod; begin - if selector = nil then - raise new ArgumentNullException('selector'); + var enumerator := Self.GetEnumerator(); + if not enumerator.MoveNext() then + raise new System.ArgumentException(GetTranslation(SEQUENCE_CANNOT_BE_EMPTY)); + var minElement := enumerator.Current; + var minKey := keySelector(minElement); + var comp := Comparer&.Default; - Result := Self.Aggregate((min, x)-> comp.Compare(selector(x), selector(min)) <= 0 ? x : min); + while enumerator.MoveNext() do + begin + var currentElement := enumerator.Current; + var currentKey := keySelector(currentElement); + if comp.Compare(currentKey,minKey) <= 0 then + begin + minKey := currentKey; + minElement := currentElement; + end; + end; + + Result := minElement; end; /// Возвращает последний элемент последовательности с максимальным значением ключа -function LastMaxBy(Self: sequence of T; selector: T->TKey): T; extensionmethod; +function LastMaxBy(Self: sequence of T; keySelector: T -> TKey): T; extensionmethod; begin - if selector = nil then - raise new ArgumentNullException('selector'); + var enumerator := Self.GetEnumerator(); + if not enumerator.MoveNext() then + raise new System.ArgumentException(GetTranslation(SEQUENCE_CANNOT_BE_EMPTY)); + var maxElement := enumerator.Current; + var maxKey := keySelector(maxElement); + var comp := Comparer&.Default; - Result := Self.Aggregate((max, x)-> comp.Compare(selector(x), selector(max)) >= 0 ? x : max); + while enumerator.MoveNext() do + begin + var currentElement := enumerator.Current; + var currentKey := keySelector(currentElement); + if comp.Compare(currentKey,maxKey) > 0 then + begin + maxKey := currentKey; + maxElement := currentElement; + end; + end; + + Result := maxElement; end; {function TakeLast(Self: sequence of T; count: integer): sequence of T; extensionmethod; @@ -11672,7 +11734,100 @@ end; function LastIndexMax(Self: List): integer; extensionmethod; where T: System.IComparable; begin Result := Self.LastIndexMax(Self.Count - 1); -end; +end; + +/// Возвращает индекс первого элемента с минимальным значением ключа +function IndexMinBy(Self: array of T; keySelector: T -> TKey): integer; extensionmethod; +begin + if Self.Length = 0 then + raise new System.ArgumentException(ARRAY_CANNOT_BE_EMPTY); + + var minIndex := 0; + var minKey := keySelector(Self[0]); + + var comp := Comparer&.Default; + for var i := 1 to Self.Length - 1 do + begin + var currentKey := keySelector(Self[i]); + if comp.Compare(currentKey,minKey) < 0 then + begin + minKey := currentKey; + minIndex := i; + end; + end; + + Result := minIndex; +end; + +/// Возвращает индекс первого элемента с максимальным значением ключа +function IndexMaxBy(Self: array of T; keySelector: T -> TKey): integer; extensionmethod; +begin + if Self.Length = 0 then + raise new System.ArgumentException(ARRAY_CANNOT_BE_EMPTY); + + var maxIndex := 0; + var maxKey := keySelector(Self[0]); + + var comp := Comparer&.Default; + for var i := 1 to Self.Length - 1 do + begin + var currentKey := keySelector(Self[i]); + if comp.Compare(currentKey,maxKey) > 0 then + begin + maxKey := currentKey; + maxIndex := i; + end; + end; + + Result := maxIndex; +end; + +/// Возвращает индекс последнего элемента с минимальным значением ключа +function LastIndexMinBy(Self: array of T; keySelector: T -> TKey): integer; extensionmethod; +begin + if Self.Length = 0 then + raise new System.ArgumentException(ARRAY_CANNOT_BE_EMPTY); + + var minIndex := 0; + var minKey := keySelector(Self[0]); + + var comp := Comparer&.Default; + for var i := 1 to Self.Length - 1 do + begin + var currentKey := keySelector(Self[i]); + if comp.Compare(currentKey,minKey) <= 0 then + begin + minKey := currentKey; + minIndex := i; + end; + end; + + Result := minIndex; +end; + +/// Возвращает индекс последнего элемента с максимальным значением ключа +function LastIndexMaxBy(Self: array of T; keySelector: T -> TKey): integer; extensionmethod; +begin + if Self.Length = 0 then + raise new System.ArgumentException(ARRAY_CANNOT_BE_EMPTY); + + var maxIndex := 0; + var maxKey := keySelector(Self[0]); + + var comp := Comparer&.Default; + for var i := 1 to Self.Length - 1 do + begin + var currentKey := keySelector(Self[i]); + if comp.Compare(currentKey,maxKey) >= 0 then + begin + maxKey := currentKey; + maxIndex := i; + end; + end; + + Result := maxIndex; +end; + /// Заменяет в массиве все вхождения одного значения на другое /// Заменяет в списке все вхождения одного значения на другое @@ -12716,7 +12871,7 @@ begin Result := Self[i]; end; -/// Возвращает индекс первого минимального элемента начиная с позиции index +/// Возвращает индекс первого минимального элемента function IndexMin(Self: array of T; index: integer := 0): integer; extensionmethod; where T: IComparable; begin var min := Self[index]; @@ -12729,7 +12884,7 @@ begin end; end; -/// Возвращает индекс первого максимального элемента начиная с позиции index +/// Возвращает индекс первого максимального элемента function IndexMax(Self: array of T; index: integer := 0): integer; extensionmethod; where T: System.IComparable; begin var max := Self[index]; diff --git a/bin/Lib/Coords.pas b/bin/Lib/Coords.pas index 0a44fe5a1..5bfa0ab4f 100644 --- a/bin/Lib/Coords.pas +++ b/bin/Lib/Coords.pas @@ -635,6 +635,12 @@ type Redraw; end; + static procedure KeyPress(c: char); + begin + if c.ToLower = 's' then + Window.SaveToClipboard; + end; + static procedure Resize; begin Redraw; @@ -647,8 +653,9 @@ initialization Window.Title := 'Система координат'; finalization Redraw; - OnMouseWheel := Handlers.MouseWheel; - OnMouseDown := Handlers.MouseDown; - OnMouseMove := Handlers.MouseMove; - OnResize := Handlers.Resize; + OnMouseWheel += Handlers.MouseWheel; + OnMouseDown += Handlers.MouseDown; + OnMouseMove += Handlers.MouseMove; + OnResize += Handlers.Resize; + OnKeyPress += Handlers.KeyPress; end. \ No newline at end of file diff --git a/bin/Lib/GraphWPF.pas b/bin/Lib/GraphWPF.pas index c0bdc245a..64d67f355 100644 --- a/bin/Lib/GraphWPF.pas +++ b/bin/Lib/GraphWPF.pas @@ -230,6 +230,8 @@ type function Center: Point; /// Сохраняет содержимое графического окна в файл с именем fname procedure Save(fname: string); + /// Сохраняет содержимое графического окна в буфер обмена + procedure SaveToClipboard; /// Восстанавливает содержимое графического окна из файла с именем fname procedure Load(fname: string); /// Заполняет содержимое графического окна обоями из файла с именем fname @@ -249,6 +251,8 @@ type public /// Сохраняет содержимое графического окна в файл с именем fname procedure Save(fname: string); + /// Сохраняет содержимое графического окна в буфер обмена + procedure SaveToClipboard; /// Восстанавливает содержимое графического окна из файла с именем fname procedure Load(fname: string); /// Очищает графическое окно белым цветом @@ -2005,7 +2009,7 @@ begin end; function GraphWindowType.GetHeight := InvokeReal(GraphWindowTypeGetHeightP); -procedure SaveWindowP(canvas: FrameworkElement; filename: string); +function SaveWindowToBitmapP(canvas: FrameworkElement): BitmapSource; begin HostToRenderBitmap; var (scalex,scaley) := ScaleToDevice; @@ -2042,6 +2046,19 @@ begin bmp.Render(canvas); + Result := bmp; +end; + +procedure SaveWindowToClipboardP(canvas: FrameworkElement); +begin + var bmp := SaveWindowToBitmapP(canvas); + Clipboard.SetImage(bmp) +end; + +procedure SaveWindowP(canvas: FrameworkElement; filename: string); +begin + var bmp := SaveWindowToBitmapP(canvas); + dpic[filename] := bmp; (canvas as MyVisualHost).children.RemoveAt(0); @@ -2066,6 +2083,8 @@ end; procedure GraphWindowType.Save(fname: string) := Invoke(SaveWindowP,host,fname); +procedure GraphWindowType.SaveToClipboard := Invoke(SaveWindowToClipboardP,host); + procedure GraphWindowType.Load(fname: string) := DrawImageUnscaled(0,0,fname); procedure GraphWindowType.Fill(fname: string); @@ -2088,6 +2107,8 @@ function GraphWindowType.ClientRect: GRect := Rect(0,0,Width,Height); procedure WindowTypeWPF.Save(fname: string) := GraphWindow.Save(fname); +procedure WindowTypeWPF.SaveToClipboard := GraphWindow.SaveToClipboard; + procedure WindowTypeWPF.Load(fname: string) := GraphWindow.Load(fname); procedure WindowTypeClearP; diff --git a/bin/Lib/PABCSystem.pas b/bin/Lib/PABCSystem.pas index 402cf81f5..308a1be83 100644 --- a/bin/Lib/PABCSystem.pas +++ b/bin/Lib/PABCSystem.pas @@ -3013,6 +3013,8 @@ const Format_InvalidString = 'Входная строка имела неверный формат!!Input string was not in a correct format'; Overflow_Int32 = 'Целочисленное переполнение!!Integer overflow'; FOR_STEP_CANNOT_BE_EQUAL0 = 'Шаг цикла for не может быт равен 0!!Step of the for loop cannot be equal to 0'; + SEQUENCE_CANNOT_BE_EMPTY = 'Последовательность не может быть пустой!!Sequence cannot be empty'; + ARRAY_CANNOT_BE_EMPTY = 'Массив не может быть пустым!!Array cannot be empty'; // ----------------------------------------------------- // WINAPI // ----------------------------------------------------- @@ -11007,43 +11009,103 @@ end; // Дополнения 2024: Zip - синоним ZipTuple /// Возвращает первый элемент последовательности с минимальным значением ключа -function MinBy(Self: sequence of T; selector: T->TKey): T; extensionmethod; +function MinBy(Self: sequence of T; keySelector: T -> TKey): T; extensionmethod; begin - if selector = nil then - raise new ArgumentNullException('selector'); + var enumerator := Self.GetEnumerator(); + if not enumerator.MoveNext() then + raise new System.ArgumentException(GetTranslation(SEQUENCE_CANNOT_BE_EMPTY)); + var minElement := enumerator.Current; + var minKey := keySelector(minElement); + var comp := Comparer&.Default; - Result := Self.Aggregate((min, x)-> comp.Compare(selector(x), selector(min)) < 0 ? x : min); + while enumerator.MoveNext() do + begin + var currentElement := enumerator.Current; + var currentKey := keySelector(currentElement); + if comp.Compare(currentKey,minKey) < 0 then + begin + minKey := currentKey; + minElement := currentElement; + end; + end; + + Result := minElement; end; /// Возвращает первый элемент последовательности с максимальным значением ключа -function MaxBy(Self: sequence of T; selector: T->TKey): T; extensionmethod; +function MaxBy(Self: sequence of T; keySelector: T -> TKey): T; extensionmethod; begin - if selector = nil then - raise new ArgumentNullException('selector'); + var enumerator := Self.GetEnumerator(); + if not enumerator.MoveNext() then + raise new System.ArgumentException(GetTranslation(SEQUENCE_CANNOT_BE_EMPTY)); + var maxElement := enumerator.Current; + var maxKey := keySelector(maxElement); + var comp := Comparer&.Default; - Result := Self.Aggregate((max, x)-> comp.Compare(selector(x), selector(max)) > 0 ? x : max); + while enumerator.MoveNext() do + begin + var currentElement := enumerator.Current; + var currentKey := keySelector(currentElement); + if comp.Compare(currentKey,maxKey) > 0 then + begin + maxKey := currentKey; + maxElement := currentElement; + end; + end; + + Result := maxElement; end; /// Возвращает последний элемент последовательности с минимальным значением ключа -function LastMinBy(Self: sequence of T; selector: T->TKey): T; extensionmethod; +function LastMinBy(Self: sequence of T; keySelector: T -> TKey): T; extensionmethod; begin - if selector = nil then - raise new ArgumentNullException('selector'); + var enumerator := Self.GetEnumerator(); + if not enumerator.MoveNext() then + raise new System.ArgumentException(GetTranslation(SEQUENCE_CANNOT_BE_EMPTY)); + var minElement := enumerator.Current; + var minKey := keySelector(minElement); + var comp := Comparer&.Default; - Result := Self.Aggregate((min, x)-> comp.Compare(selector(x), selector(min)) <= 0 ? x : min); + while enumerator.MoveNext() do + begin + var currentElement := enumerator.Current; + var currentKey := keySelector(currentElement); + if comp.Compare(currentKey,minKey) <= 0 then + begin + minKey := currentKey; + minElement := currentElement; + end; + end; + + Result := minElement; end; /// Возвращает последний элемент последовательности с максимальным значением ключа -function LastMaxBy(Self: sequence of T; selector: T->TKey): T; extensionmethod; +function LastMaxBy(Self: sequence of T; keySelector: T -> TKey): T; extensionmethod; begin - if selector = nil then - raise new ArgumentNullException('selector'); + var enumerator := Self.GetEnumerator(); + if not enumerator.MoveNext() then + raise new System.ArgumentException(GetTranslation(SEQUENCE_CANNOT_BE_EMPTY)); + var maxElement := enumerator.Current; + var maxKey := keySelector(maxElement); + var comp := Comparer&.Default; - Result := Self.Aggregate((max, x)-> comp.Compare(selector(x), selector(max)) >= 0 ? x : max); + while enumerator.MoveNext() do + begin + var currentElement := enumerator.Current; + var currentKey := keySelector(currentElement); + if comp.Compare(currentKey,maxKey) > 0 then + begin + maxKey := currentKey; + maxElement := currentElement; + end; + end; + + Result := maxElement; end; {function TakeLast(Self: sequence of T; count: integer): sequence of T; extensionmethod; @@ -11672,7 +11734,100 @@ end; function LastIndexMax(Self: List): integer; extensionmethod; where T: System.IComparable; begin Result := Self.LastIndexMax(Self.Count - 1); -end; +end; + +/// Возвращает индекс первого элемента с минимальным значением ключа +function IndexMinBy(Self: array of T; keySelector: T -> TKey): integer; extensionmethod; +begin + if Self.Length = 0 then + raise new System.ArgumentException(ARRAY_CANNOT_BE_EMPTY); + + var minIndex := 0; + var minKey := keySelector(Self[0]); + + var comp := Comparer&.Default; + for var i := 1 to Self.Length - 1 do + begin + var currentKey := keySelector(Self[i]); + if comp.Compare(currentKey,minKey) < 0 then + begin + minKey := currentKey; + minIndex := i; + end; + end; + + Result := minIndex; +end; + +/// Возвращает индекс первого элемента с максимальным значением ключа +function IndexMaxBy(Self: array of T; keySelector: T -> TKey): integer; extensionmethod; +begin + if Self.Length = 0 then + raise new System.ArgumentException(ARRAY_CANNOT_BE_EMPTY); + + var maxIndex := 0; + var maxKey := keySelector(Self[0]); + + var comp := Comparer&.Default; + for var i := 1 to Self.Length - 1 do + begin + var currentKey := keySelector(Self[i]); + if comp.Compare(currentKey,maxKey) > 0 then + begin + maxKey := currentKey; + maxIndex := i; + end; + end; + + Result := maxIndex; +end; + +/// Возвращает индекс последнего элемента с минимальным значением ключа +function LastIndexMinBy(Self: array of T; keySelector: T -> TKey): integer; extensionmethod; +begin + if Self.Length = 0 then + raise new System.ArgumentException(ARRAY_CANNOT_BE_EMPTY); + + var minIndex := 0; + var minKey := keySelector(Self[0]); + + var comp := Comparer&.Default; + for var i := 1 to Self.Length - 1 do + begin + var currentKey := keySelector(Self[i]); + if comp.Compare(currentKey,minKey) <= 0 then + begin + minKey := currentKey; + minIndex := i; + end; + end; + + Result := minIndex; +end; + +/// Возвращает индекс последнего элемента с максимальным значением ключа +function LastIndexMaxBy(Self: array of T; keySelector: T -> TKey): integer; extensionmethod; +begin + if Self.Length = 0 then + raise new System.ArgumentException(ARRAY_CANNOT_BE_EMPTY); + + var maxIndex := 0; + var maxKey := keySelector(Self[0]); + + var comp := Comparer&.Default; + for var i := 1 to Self.Length - 1 do + begin + var currentKey := keySelector(Self[i]); + if comp.Compare(currentKey,maxKey) >= 0 then + begin + maxKey := currentKey; + maxIndex := i; + end; + end; + + Result := maxIndex; +end; + /// Заменяет в массиве все вхождения одного значения на другое /// Заменяет в списке все вхождения одного значения на другое @@ -12716,7 +12871,7 @@ begin Result := Self[i]; end; -/// Возвращает индекс первого минимального элемента начиная с позиции index +/// Возвращает индекс первого минимального элемента function IndexMin(Self: array of T; index: integer := 0): integer; extensionmethod; where T: IComparable; begin var min := Self[index]; @@ -12729,7 +12884,7 @@ begin end; end; -/// Возвращает индекс первого максимального элемента начиная с позиции index +/// Возвращает индекс первого максимального элемента function IndexMax(Self: array of T; index: integer := 0): integer; extensionmethod; where T: System.IComparable; begin var max := Self[index];