From f3a14f3cb940261b6d5a419fbd41cfed72c7f0e4 Mon Sep 17 00:00:00 2001 From: Sun Serega Date: Sun, 22 Jun 2025 20:20:22 +0300 Subject: [PATCH] =?UTF-8?q?`.AdjacentGroupBy`=20-=20`.AdjacentGroup`=20?= =?UTF-8?q?=D1=81=20=D1=84=D1=83=D0=BD=D0=BA=D1=86=D0=B8=D0=B5=D0=B9=20?= =?UTF-8?q?=D0=BA=D0=BB=D1=8E=D1=87=D0=B5=D0=B9=20(#3085)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * `.AdjacentGroupBy` * Комментарии * regen doc XML * return `IGrouping` --- bin/Lib/PABCSystem.pas | 50 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/bin/Lib/PABCSystem.pas b/bin/Lib/PABCSystem.pas index b14736921..b46da6319 100644 --- a/bin/Lib/PABCSystem.pas +++ b/bin/Lib/PABCSystem.pas @@ -11948,7 +11948,55 @@ begin yield c.TakeGroup().ToArray; end; -// ToDo Сделать AdjacentGroup с функцией сравнения +type + AdjacentGroupByResult = sealed auto class(System.Linq.IGrouping) + public auto property Key: TKey; + public auto property Elements: sequence of TResult; + + public function GetEnumerator: IEnumerator := Elements.GetEnumerator; + public function System.Collections.IEnumerable.GetEnumerator: System.Collections.IEnumerator := GetEnumerator; + + end; + +/// Группирует подряд идущие элементы с одинаковыми значениями ключами +/// Использует компаратор comp +function AdjacentGroupBy(self: sequence of T; by: T->TKey; comp: IEqualityComparer): sequence of System.Linq.IGrouping; extensionmethod; +begin + var enmr := self.GetEnumerator; + if not enmr.MoveNext then exit; + if comp=nil then comp := System.Collections.Generic.EqualityComparer&.Default; + + var l := new List; + var key: TKey; + begin + var o := enmr.Current; + l += o; + key := by(o); + end; + var key_hc := comp.GetHashCode(key); + + while enmr.MoveNext do + begin + var o := enmr.Current; + var n_key := by(o); + var n_key_hc := comp.GetHashCode(n_key); + + if (n_key_hc<>key_hc) or not comp.Equals(n_key, key) then + begin + yield new AdjacentGroupByResult(key, l.ToArray); + l.Clear; + key := n_key; + key_hc := n_key_hc; + end; + + l += o; + end; + + yield new AdjacentGroupByResult(key, l.ToArray); +end; +/// Группирует подряд идущие элементы с одинаковыми значениями ключами +/// Использует компаратор по-умолчанию +function AdjacentGroupBy(self: sequence of T; by: T->TKey); extensionmethod := self.AdjacentGroupBy(by, nil); /// Возвращает количество элементов, равных указанному значению function CountOf(Self: sequence of T; x: T): integer; extensionmethod;