<?xml version='1.0' encoding="utf-8"?>
      <rss version='2.0'>
      <channel>
      <title>Форум на Исходниках.RU</title>
      <link>https://forum.sources.ru</link>
      <description>Форум на Исходниках.RU</description>
      <generator>Форум на Исходниках.RU</generator>
  	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3796148</guid>
        <pubDate>Sun, 21 Apr 2019 06:57:27 +0000</pubDate>
        <title>Spring4D</title>
        <link>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3796148</link>
        <description><![CDATA[Cfon: Тот же пример на Ньютоне <br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">импорт</div><div class="code_line">&nbsp;&nbsp;Система.СисУтилиты,</div><div class="code_line">&nbsp;&nbsp;Система.Мат,</div><div class="code_line">&nbsp;&nbsp;Спринг.Коллекции;</div><div class="code_line">&nbsp;</div><div class="code_line">ТПет: запись</div><div class="code_line">&nbsp;&nbsp;Имя: строка;</div><div class="code_line">&nbsp;&nbsp;Возраст: дабл;</div><div class="code_line">&nbsp;&nbsp;конструктор: (ПИмя: строка; ПВозраст: дабл) -- Имя = ПИмя; Возраст = ПВозраст;</div><div class="code_line">конец;</div><div class="code_line">&nbsp;</div><div class="code_line">ТТоталИнфо: запись</div><div class="code_line">&nbsp;&nbsp;Ключ: целое;</div><div class="code_line">&nbsp;&nbsp;Колво: целое;</div><div class="code_line">&nbsp;&nbsp;Мин: дабл;</div><div class="code_line">&nbsp;&nbsp;Макс: дабл;</div><div class="code_line">&nbsp;&nbsp;конструктор: (ПКлюч, ПКолво: целое; ПМин, ПМакс: дабл)</div><div class="code_line">&nbsp;&nbsp;начать</div><div class="code_line">&nbsp;&nbsp; &nbsp;Ключ = ПКлюч;</div><div class="code_line">&nbsp;&nbsp; &nbsp;Колво = ПКолво;</div><div class="code_line">&nbsp;&nbsp; &nbsp;Мин = ПМин;</div><div class="code_line">&nbsp;&nbsp; &nbsp;Макс = ПМакс;</div><div class="code_line">&nbsp;&nbsp;конец;</div><div class="code_line">конец;</div><div class="code_line">&nbsp;</div><div class="code_line">ГруппироватьПоПример: функция</div><div class="code_line">начать</div><div class="code_line">&nbsp;&nbsp;// Создать список домашних животных.</div><div class="code_line">&nbsp;&nbsp;пер ПетСписок = ТКоллекции.Список(</div><div class="code_line">&nbsp;&nbsp; &nbsp;ТПет(&#39;Барли&#39;, 8.3),</div><div class="code_line">&nbsp;&nbsp; &nbsp;ТПет(&#39;Бутс&#39;, 4.9),</div><div class="code_line">&nbsp;&nbsp; &nbsp;ТПет(&#39;Вислерс&#39;, 1.5),</div><div class="code_line">&nbsp;&nbsp; &nbsp;ТПет(&#39;Дайзи&#39;, 4.3)</div><div class="code_line">&nbsp;&nbsp;);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;пер запрос = ТПеречислимый.ГруппироватьПо(ПетСписок,</div><div class="code_line">&nbsp;&nbsp; &nbsp;(пет: ТПет) -- вернуть Флор(пет.Возраст),</div><div class="code_line">&nbsp;&nbsp; &nbsp;(пет: ТПет) -- вернуть пет.Возраст,</div><div class="code_line">&nbsp;&nbsp; &nbsp;(базВозраст: целое; возрасты: ИПеречислимый&#60;дабл&#62;) --</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;вернуть ТТоталИнфо(базВозраст, возрасты.Колво, возрасты.Мин, возрасты.Макс)</div><div class="code_line">&nbsp;&nbsp;);</div><div class="code_line">&nbsp;&nbsp;</div><div class="code_line">&nbsp;&nbsp;цикл по запрос -- результат</div><div class="code_line">&nbsp;&nbsp;начать</div><div class="code_line">&nbsp;&nbsp; &nbsp;Вывод(&#39;Группа возраст: &#39;, результат.Ключ);</div><div class="code_line">&nbsp;&nbsp; &nbsp;Вывод(&#39;Число петс в этой возрастной группе: &#39;, результат.Колво);</div><div class="code_line">&nbsp;&nbsp; &nbsp;Вывод(Формат(&#39;Минимальный возраст: *&#39;, [результат.Мин]));</div><div class="code_line">&nbsp;&nbsp; &nbsp;Вывод(Формат(&#39;Максимальный возраст: *&#39;, [результат.Макс]));</div><div class="code_line">&nbsp;&nbsp;конец;</div><div class="code_line">конец;</div></ol></div></div></div></div><script>preloadCodeButtons('1');</script><br>
- Коуч что это?  :blink: <br>
Это друг мой новий язык программирования НЬЮТОН&#33;  :jokingly:  :jokingly:<br>
Давно хотел понять что ощущают англоязычные коллеги  :blush:]]></description>
        <author>Cfon</author>
        <category>Delphi: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3796091</guid>
        <pubDate>Fri, 19 Apr 2019 19:11:28 +0000</pubDate>
        <title>Spring4D</title>
        <link>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3796091</link>
        <description><![CDATA[Cfon: Пример средней сложности GroupBy:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">uses</div><div class="code_line">&nbsp;&nbsp;System.SysUtils,</div><div class="code_line">&nbsp;&nbsp;System.Math,</div><div class="code_line">&nbsp;&nbsp;Spring.Collections;</div><div class="code_line">&nbsp;</div><div class="code_line">type</div><div class="code_line">&nbsp;&nbsp;TPet = record</div><div class="code_line">&nbsp;&nbsp; &nbsp;Name: string;</div><div class="code_line">&nbsp;&nbsp; &nbsp;Age: double;</div><div class="code_line">&nbsp;&nbsp; &nbsp;constructor Create(AName: string; AAge: double);</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;TTotalInfo = record</div><div class="code_line">&nbsp;&nbsp; &nbsp;Key: integer;</div><div class="code_line">&nbsp;&nbsp; &nbsp;Count: integer;</div><div class="code_line">&nbsp;&nbsp; &nbsp;Min: double;</div><div class="code_line">&nbsp;&nbsp; &nbsp;Max: double;</div><div class="code_line">&nbsp;&nbsp; &nbsp;constructor Create(AKey, ACount: integer; AMin, AMax: double);</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;</div><div class="code_line">{ TPet }</div><div class="code_line">&nbsp;</div><div class="code_line">constructor TPet.Create(AName: string; AAge: double);</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;Name:= AName;</div><div class="code_line">&nbsp;&nbsp;Age:= AAge;</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">{ TTotalInfo }</div><div class="code_line">&nbsp;</div><div class="code_line">constructor TTotalInfo.Create(AKey, ACount: integer; AMin, AMax: double);</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;Key:= AKey;</div><div class="code_line">&nbsp;&nbsp;Count:= ACount;</div><div class="code_line">&nbsp;&nbsp;Min:= AMin;</div><div class="code_line">&nbsp;&nbsp;Max:= AMax;</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;// Create a list of pets.</div><div class="code_line">&nbsp;&nbsp;var PetsList:= TCollections.CreateList&#60;TPet&#62;([</div><div class="code_line">&nbsp;&nbsp; &nbsp;TPet.Create(&#39;Barley&#39;, 8.3),</div><div class="code_line">&nbsp;&nbsp; &nbsp;TPet.Create(&#39;Boots&#39;, 4.9),</div><div class="code_line">&nbsp;&nbsp; &nbsp;TPet.Create(&#39;Whislers&#39;, 1.5),</div><div class="code_line">&nbsp;&nbsp; &nbsp;TPet.Create(&#39;Daisy&#39;, 4.3)</div><div class="code_line">&nbsp;&nbsp;]);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// Group Pet.Age values by the Math.Floor of the age.</div><div class="code_line">&nbsp;&nbsp;// Then project an anonymous type from each group</div><div class="code_line">&nbsp;&nbsp;// that consists of the key, the count of the group&#39;s</div><div class="code_line">&nbsp;&nbsp;// elements, and the minimum and maximum age in the group.</div><div class="code_line">&nbsp;&nbsp;var query:= TEnumerable.GroupBy&#60;TPet, integer, double, TTotalInfo&#62;(PetsList,</div><div class="code_line">&nbsp;&nbsp; &nbsp;function (pet: TPet): integer</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Result:= Floor(pet.Age);</div><div class="code_line">&nbsp;&nbsp; &nbsp;end,</div><div class="code_line">&nbsp;&nbsp; &nbsp;function (pet: TPet): double</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Result:= pet.Age;</div><div class="code_line">&nbsp;&nbsp; &nbsp;end,</div><div class="code_line">&nbsp;&nbsp; &nbsp;function (baseAge: integer; ages: IEnumerable&#60;double&#62;): TTotalInfo</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Result:= TTotalInfo.Create(baseAge, ages.Count, ages.Min, ages.Max);</div><div class="code_line">&nbsp;&nbsp; &nbsp;end</div><div class="code_line">&nbsp;&nbsp;);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// Iterate over each anonymous type.</div><div class="code_line">&nbsp;&nbsp;for var result in query do</div><div class="code_line">&nbsp;&nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp;Writeln;</div><div class="code_line">&nbsp;&nbsp; &nbsp;WriteLn(&#39;Age group: &#39;, result.Key);</div><div class="code_line">&nbsp;&nbsp; &nbsp;WriteLn(&#39;Number of pets in this age group: &#39;, result.Count);</div><div class="code_line">&nbsp;&nbsp; &nbsp;WriteLn(Format(&#39;Minimum age: %.1f&#39;, [result.Min]));</div><div class="code_line">&nbsp;&nbsp; &nbsp;WriteLn(Format(&#39;Maximum age: %.1f&#39;, [result.Max]));</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">end;</div><div class="code_line">(* C# code</div><div class="code_line">&nbsp;&nbsp; &nbsp;// Create a list of pets.</div><div class="code_line">&nbsp;&nbsp; &nbsp;List&#60;Pet&#62; petsList =</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;new List&#60;Pet&#62;{ new Pet { Name=&quot;Barley&quot;, Age=8.3 },</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; new Pet { Name=&quot;Boots&quot;, Age=4.9 },</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; new Pet { Name=&quot;Whiskers&quot;, Age=1.5 },</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; new Pet { Name=&quot;Daisy&quot;, Age=4.3 } };</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;// Group Pet.Age values by the Math.Floor of the age.</div><div class="code_line">&nbsp;&nbsp; &nbsp;// Then project an anonymous type from each group</div><div class="code_line">&nbsp;&nbsp; &nbsp;// that consists of the key, the count of the group&#39;s</div><div class="code_line">&nbsp;&nbsp; &nbsp;// elements, and the minimum and maximum age in the group.</div><div class="code_line">&nbsp;&nbsp; &nbsp;var query = petsList.GroupBy(</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;pet =&#62; Math.Floor(pet.Age),</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;pet =&#62; pet.Age,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;(baseAge, ages) =&#62; new</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Key = baseAge,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Count = ages.Count(),</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Min = ages.Min(),</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Max = ages.Max()</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;});</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;// Iterate over each type.</div><div class="code_line">&nbsp;&nbsp; &nbsp;foreach (var result in query)</div><div class="code_line">&nbsp;&nbsp; &nbsp;{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Console.WriteLine(&quot;\nAge group: &quot; + result.Key);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Console.WriteLine(&quot;Number of pets in this age group: &quot; + result.Count);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Console.WriteLine(&quot;Minimum age: &quot; + result.Min);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Console.WriteLine(&quot;Maximum age: &quot; + result.Max);</div><div class="code_line">&nbsp;&nbsp; &nbsp;}</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;/* &nbsp;This code produces the following output:</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Age group: 8</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Number of pets in this age group: 1</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Minimum age: 8.3</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Maximum age: 8.3</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Age group: 4</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Number of pets in this age group: 2</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Minimum age: 4.3</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Maximum age: 4.9</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Age group: 1</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Number of pets in this age group: 1</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Minimum age: 1.5</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Maximum age: 1.5</div><div class="code_line">&nbsp;&nbsp; &nbsp;*/*)</div><div class="code_line">end.</div></ol></div></div></div></div>]]></description>
        <author>Cfon</author>
        <category>Delphi: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3796069</guid>
        <pubDate>Fri, 19 Apr 2019 13:01:50 +0000</pubDate>
        <title>Spring4D</title>
        <link>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3796069</link>
        <description><![CDATA[Cfon: Пример с уже знакомым Aggregate + Union + Empty.<br>
Aggregate - сведение, Union - объдинение, Empty - пустой массив. <br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">uses</div><div class="code_line">&nbsp;&nbsp;Spring.Collections,</div><div class="code_line">&nbsp;&nbsp;Spring.Collections.Enumerable;</div><div class="code_line">&nbsp;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;var names1 := TCollections.CreateList&#60;string&#62;([</div><div class="code_line">&nbsp;&nbsp; &nbsp;&#39;Hartono, Tommy&#39;</div><div class="code_line">&nbsp;&nbsp;]);</div><div class="code_line">&nbsp;&nbsp;var names2 := TCollections.CreateList&#60;string&#62;([</div><div class="code_line">&nbsp;&nbsp; &nbsp;&#39;Adams, Terry&#39;,</div><div class="code_line">&nbsp;&nbsp; &nbsp;&#39;Andersen, Henriette Thaulow&#39;,</div><div class="code_line">&nbsp;&nbsp; &nbsp;&#39;Hedlund, Magnus&#39;,</div><div class="code_line">&nbsp;&nbsp; &nbsp;&#39;Ito, Shu&#39;</div><div class="code_line">&nbsp;&nbsp;]);</div><div class="code_line">&nbsp;&nbsp;var names3 := TCollections.CreateList&#60;string&#62;([</div><div class="code_line">&nbsp;&nbsp; &nbsp;&#39;Solanki, Ajay&#39;,</div><div class="code_line">&nbsp;&nbsp; &nbsp;&#39;Hoeing, Helge&#39;,</div><div class="code_line">&nbsp;&nbsp; &nbsp;&#39;Andersen, Henriette Thaulow&#39;,</div><div class="code_line">&nbsp;&nbsp; &nbsp;&#39;Potra, Cristina&#39;,</div><div class="code_line">&nbsp;&nbsp; &nbsp;&#39;Iallo, Lucio&#39;</div><div class="code_line">&nbsp;&nbsp;]);</div><div class="code_line">&nbsp;&nbsp;var NamesList:= TCollections.CreateList&#60;IList&#60;string&#62;&#62;([names1, names2, names3]);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// Only include arrays that have four or more elements</div><div class="code_line">&nbsp;&nbsp;var AllNames:= Enumerable&#60;IList&#60;string&#62;&#62;.Create(NamesList.ToArray)</div><div class="code_line">&nbsp;&nbsp; &nbsp;.Aggregate&#60;IEnumerable&#60;string&#62;&#62;(TEnumerable.Empty&#60;string&#62;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;function (current: IEnumerable&#60;string&#62;; next: IList&#60;string&#62;): IEnumerable&#60;string&#62;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Result:= current;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;if next.Count &#62; 3 then</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Result:= TEnumerable.Union&#60;string&#62;(current, next);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;end</div><div class="code_line">&nbsp;&nbsp; &nbsp;);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// print</div><div class="code_line">&nbsp;&nbsp;for var name in AllNames do</div><div class="code_line">&nbsp;&nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp;Writeln(name);</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;</div><div class="code_line">(*C# code</div><div class="code_line">&nbsp;&nbsp;string[] names1 = { &quot;Hartono, Tommy&quot; };</div><div class="code_line">&nbsp;&nbsp;string[] names2 = { &quot;Adams, Terry&quot;, &quot;Andersen, Henriette Thaulow&quot;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&quot;Hedlund, Magnus&quot;, &quot;Ito, Shu&quot; };</div><div class="code_line">&nbsp;&nbsp;string[] names3 = { &quot;Solanki, Ajay&quot;, &quot;Hoeing, Helge&quot;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&quot;Andersen, Henriette Thaulow&quot;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&quot;Potra, Cristina&quot;, &quot;Iallo, Lucio&quot; };</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;List&#60;string[]&#62; namesList =</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;new List&#60;string[]&#62; { names1, names2, names3 };</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// Only include arrays that have four or more elements</div><div class="code_line">&nbsp;&nbsp;IEnumerable&#60;string&#62; allNames =</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;namesList.Aggregate(Enumerable.Empty&#60;string&#62;(),</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;(current, next) =&#62; next.Length &#62; 3 ? current.Union(next) : current);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;foreach (string name in allNames)</div><div class="code_line">&nbsp;&nbsp;{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Console.WriteLine(name);</div><div class="code_line">&nbsp;&nbsp;}</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;/*</div><div class="code_line">&nbsp;&nbsp; This code produces the following output:</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; Adams, Terry</div><div class="code_line">&nbsp;&nbsp; Andersen, Henriette Thaulow</div><div class="code_line">&nbsp;&nbsp; Hedlund, Magnus</div><div class="code_line">&nbsp;&nbsp; Ito, Shu</div><div class="code_line">&nbsp;&nbsp; Solanki, Ajay</div><div class="code_line">&nbsp;&nbsp; Hoeing, Helge</div><div class="code_line">&nbsp;&nbsp; Potra, Cristina</div><div class="code_line">&nbsp;&nbsp; Iallo, Lucio</div><div class="code_line">&nbsp;&nbsp;*/*)</div><div class="code_line">end.</div></ol></div></div></div></div><br>
Что то подобное мы уже делали...]]></description>
        <author>Cfon</author>
        <category>Delphi: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3796060</guid>
        <pubDate>Fri, 19 Apr 2019 11:23:28 +0000</pubDate>
        <title>Spring4D</title>
        <link>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3796060</link>
        <description><![CDATA[Cfon: - Коуч, при всем уважении, но я думаю что лучше удалять прямо из списка sts  :huh: <br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">strs.Remove(&#39;banana&#39;);</div></ol></div></div></div></div><br>
Да Новичок ты прав&#33; Черт побери&#33;  :D <br>
При всех преимуществах функционального подхода, не стоит игнорировать императивный стиль, ибо в конце концов нам придеться взаимодействовать с гуем например, чтобы изменять состояние в разных его окошках. <br>
В данном случае чтоб удалить банан  :D естественно надо юзать Remove, при условии конешно, если нам надо изменить сам strs. Преимущество Делфи в том что тут можно совместит два смежной методики, програмируя бизнес-логики приложения в функциональном стиле, а гуй в императивном.]]></description>
        <author>Cfon</author>
        <category>Delphi: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3796052</guid>
        <pubDate>Fri, 19 Apr 2019 07:42:49 +0000</pubDate>
        <title>Spring4D</title>
        <link>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3796052</link>
        <description><![CDATA[Cfon: Новичок&#33; :D  <br>
- Да учитель?  :huh: <br>
Учитель :lool: <br>
Зови меня Коуч :D <br>
- Ок Коуч :jokingly: <br>
- А кто это пардон? :huh: <br>
:blink: неважно :D <br>
Короче студент пока ты спал я тут немного код поменял в посте #45. Заменил TComparison&lt;T&gt; на TEqualityComparison&lt;T&gt; ибо TComparison возвращал integer, а нам надо boolean что приводило к лишним проверкам.<br>
- О Коуч так действительно более логично  :)<br>
- У меня вопрос<br>
Какой?<br>
- Что такое чистые функции? Вы вначале писали.<br>
Чистыми называют те функции, которые что-то получают и что-то возвращяют, при этом они не должны изменять какие-то внешние состояния.<br>
- Примерчик можно?  :huh: <br>
Да вот например пример чистой анонимной функции: <br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">function (s: string): integer</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;Result:= Length(s);</div><div class="code_line">end</div></ol></div></div></div></div><br>
она пулучает строку, а возвращает число, ее результат полнойстью зависит от параметра и всегда возращает одно и тоже значение для одного и того же агрумента. При это в теле функции нет обращений к глобальным переменным или функциям, которые бы были не чистыми. Length тоже чистая функция, поскольку получает строку и возвращает ее длину, я просто обернул ее в анонимку  :D<br>
- Угу а почему они так важны в функционльном програмировании?<br>
По причине что не меняют внешнее состояние, что как я уже говорил является первм условием функциональной парадигмы. Кроме того чистые функции легко тестировать.<br>
- А пример грязной функции  :jokingly: <br>
Ну вот например пример  :D <br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">function(i: integer): integer</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;Result:= Random(i);</div><div class="code_line">end</div></ol></div></div></div></div><br>
Хотя она принимает один аргумент и возвращает значение, в ней есть вызов грязной функции Random, которая каждый раз возвращает разные значения для одного и того же аргумента. Или вот еще пример<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">var i:= 100;</div><div class="code_line">function: integer</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;Result:= Inc(i);</div><div class="code_line">end</div></ol></div></div></div></div><br>
Тут мы имеем дело с изменением внешней переменной.<br>
- Понятно Коуч&#33;  :D <br>
- Еще вопрос... я тут пытался понять как читать вызовы методов Spring, но тщетно  :wacko: не могли бы вы объяснить как их читать?<br>
Новичок, я сам до недавнего времени разбирался как их читать :D]]></description>
        <author>Cfon</author>
        <category>Delphi: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3796025</guid>
        <pubDate>Thu, 18 Apr 2019 20:33:08 +0000</pubDate>
        <title>Spring4D</title>
        <link>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3796025</link>
        <description><![CDATA[Cfon: - Маста, а если дефолтное сравнение не катит, что делать?  :huh: <br>
Тогда надо вынести логику сравнения наружу и дать возможность самим определить как сравнивать объекты  :) <br>
- А пример можно? <br>
Ок, смотри я немного изменил твое определение дженерика<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">class function TExample.Delete&#60;T&#62;(ASource: IEnumerable&#60;T&#62;; AValue: T;</div><div class="code_line">&nbsp;&nbsp;const AComparison: TEqualityComparison&#60;T&#62;): IEnumerable&#60;T&#62;;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;Result := ASource.Where(</div><div class="code_line">&nbsp;&nbsp; &nbsp;function (const ALeft: T): Boolean</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Result:= AComparison(ALeft, AValue); //&#60;-- тут наша логика вызывается</div><div class="code_line">&nbsp;&nbsp; &nbsp;end</div><div class="code_line">&nbsp;&nbsp;);</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">var deletedBananas:= TExample.Delete&#60;string&#62;(strs, &#39;banana&#39;,</div><div class="code_line">&nbsp;&nbsp; &nbsp;function (const Left, Right: string): integer //&#60;-- тут определяем логику через анонимку</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Result:= not (Left = Right);</div><div class="code_line">&nbsp;&nbsp; &nbsp;end</div><div class="code_line">&nbsp;&nbsp;);</div></ol></div></div></div></div><br>
- Вау&#33; Маста вы вы вы.. <br>
Что? Гений?  :popcorn: <br>
- Да однозначно :jokingly:]]></description>
        <author>Cfon</author>
        <category>Delphi: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3796012</guid>
        <pubDate>Thu, 18 Apr 2019 17:03:32 +0000</pubDate>
        <title>Spring4D</title>
        <link>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3796012</link>
        <description><![CDATA[Cfon: - Маста, а как насчет времени затраченое на копирование данных?  :huh:<br>Ну тут тоже есть свои секреты  :D <br>Как в Делфи не знаю точно, но например в Хаскеле данные, если к примеру брать два списка, не копируются, а создаются ссылки на одни и те же данные. Само копирование происходит тока тогда когда данные изменяются, вот тогда создается копия и затем эта копия изменяется. Так что никаких лишних копий нет. Заметь копия не всех данных, а ток тех что надо изменить.<br>Надо почитать про то как Делфи управляет памятью. Думаю что делфиразрабы тоже это учитывают ибо не просто так они добавили функциональные возможности типо ананимок, вывод типов, паралельное програмирование и тд.<br>- Ясно почитаю, но в Хаскеле хитро придумано :) <br>Ну как бэ не пальцем деланый язык то  :D<br>да и к слову сразу про рекурсии в Хаскеле они в итоге преобразуются на уровне бинарного кода в обычные циклы  :D так что у тут нет замедления от их юзания. <br>Ну естестно поэтому компилятор Хаскеля на порядок медленнее например чем в Делфи :D<br>В Делфи как я вижу походу самый быстрый компилятор из тех что я видел.]]></description>
        <author>Cfon</author>
        <category>Delphi: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3796000</guid>
        <pubDate>Thu, 18 Apr 2019 11:58:40 +0000</pubDate>
        <title>Spring4D</title>
        <link>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3796000</link>
        <description><![CDATA[Cfon: - Маста вот что у меня получилось, я заюзал анонимку для простоты, все как вы учили, есть вопрос<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">var Deleter := function (AValue: string): //&#60;-- что возвращать???</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Result:= strs.Where(</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;function (const s: string): Boolean</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Result:= not (s = AValue);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;end</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;);</div><div class="code_line">&nbsp;&nbsp; &nbsp;end;</div></ol></div></div></div></div><br>
Какой? <br>
- Что возвращать то?  :huh: <br>
Хороший вопрос  :D <br>
Возвращать можно что угодно, главное вернуть&#33; :D это один из принципов функционального программирования. Функции принимают что-то и возвращают что-то. Только тогда они могут быть чистыми. <br>
Ок, коль скоро мы программируем в Spring4D, то вернуть надо интерфейс IEnumerable&lt;T&gt;. В твоем случае IEnumerable&lt;string&gt;, поскольку именно его возвращает Where видишь ты ее вызов присвоил Result? Вот поэтому возвращаем IEnumerable&lt;string&gt;.<br>
- Е-е все работает&#33; <br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">var deletedBananas:= Deleter(&#39;banana&#39;);</div></ol></div></div></div></div><br>
Добже Новичок, а теперь давай сделаем еще один шаг и унифицируем нашу функцию. Ну т.е. сделаем из нее дженерик, чтобы можно было вызвать на любых данных. Сможешь?  :) <br>
- Попробую  :huh: <br>
<br>
<span class="tag-color tag-color-named" data-value="mergepost" style="color: mergepost"><span class='tag-size' data-value='7' style='font-size:7pt;'>Добавлено <time class="tag-mergetime" datetime="2019-04-18T12:38:43+00:00">18.04.19, 12:38</time></span></span><br>
- Вот че получилось, ругается  :huh: <br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">type</div><div class="code_line">&nbsp;&nbsp;TExample = record</div><div class="code_line">&nbsp;&nbsp; &nbsp;class function Delete&#60;T&#62;(ASource: IEnumerable&#60;T&#62;; AValue: T): IEnumerable&#60;T&#62;; static;</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;</div><div class="code_line">class function TExample.Delete&#60;T&#62;(ASource: IEnumerable&#60;T&#62;; AValue: T): IEnumerable&#60;T&#62;;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;Result := ASource.Where(</div><div class="code_line">&nbsp;&nbsp; &nbsp;function (const s: T): Boolean</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;if s = AValue then //&#60;-- тут ошибка &quot;E2015 Operator not applicable to this operand type&quot;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Result:= False</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;else</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Result:= True;</div><div class="code_line">&nbsp;&nbsp; &nbsp;end</div><div class="code_line">&nbsp;&nbsp;);</div><div class="code_line">end;</div></ol></div></div></div></div><br>
Новичок красавчек&#33; Ну ты уже не новичок раз такое написал&#33;  :D <br>
На счет ошибки все верно там у тебя идет проверка на равенство, компилятору неизвестно какого типа является T и как их сравнивать.<br>
- А че делать?  :huh: <br>
Юзать дефотный компарер<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">class function TExample.Delete&#60;T&#62;(ASource: IEnumerable&#60;T&#62;; AValue: T): IEnumerable&#60;T&#62;;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;Result := ASource.Where(</div><div class="code_line">&nbsp;&nbsp; &nbsp;function (const ALeft: T): Boolean</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;if TComparer&#60;T&#62;.Default.Compare(ALeft, AValue) = 0 then</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Result:= False</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;else</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Result:= True;</div><div class="code_line">&nbsp;&nbsp; &nbsp;end</div><div class="code_line">&nbsp;&nbsp;);</div><div class="code_line">end;</div></ol></div></div></div></div><br>
Начинку Default не иследовал, оставляю тебе для самостоятельного изучения  :D<br>
- Ух ты&#33; Работает&#33;  :good:<br>
<br>
- Маста функционнально прогать конешно прикольно, но память то не резиновая, это сколько же объектов будет в итоге если их все копировать и менять :wacko:<br>
Новичок ты меня удивляешь, ты что ли их копируешь? Тебе че больше всех надо? :lool:  <br>
- :huh:<br>
Лана я пошутил  :jokingly: <br>
Все дело в том что объекты не копятся не нужные объекты сразу или почти сразу удаляются&#33; Вот к примеру наш код, тут strs и deletedBananas будут удалены, как  только ссылки на них буду равны nil или они выйдут из области видимости.]]></description>
        <author>Cfon</author>
        <category>Delphi: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3795979</guid>
        <pubDate>Thu, 18 Apr 2019 07:10:50 +0000</pubDate>
        <title>Spring4D</title>
        <link>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3795979</link>
        <description><![CDATA[Cfon: Немного лекций :writer:<br>
Что отличает функциональный код от императивного?<br>
- Неизменяемые данные<br>
- Чистые функции (идемпотентные)<br>
- Функции высшего порядка (преобразование данных, композиция, рекурсия, каррирование).<br>
<br>
Ну с неизменяемостью данных понятно. В чисто функц. языках они не меняются, но делфи не является чисто функциональным языком, он просто поддерживает некоторые его концепции, но только не консистентность данных. Данные в делфи можно легко случайно изменить, поэтому надо быть внимтельным, хотя можно юзать везде константы это защитит от случайного изменения данных :D<br>
<br>
- Маста я не пойму, как прогать если данные не меняются?  :wacko: <br>
Новичок, данные меняются, но не изменяются  :blink: :lool:<br>
- Это как?  :huh: <br>
Если мы объявим переменную, то сразу записываем туда значение, потом его не изменяем. Если мы хотим изменить эти данные, то просто передаем его преобразователю данных.<br>
- Это что за хрень?  :jokingly: <br>
Так называют функции высшего порядка :punish:<br>
Например нам надо изменить массив строк, что мы делаем мы передаем его в функцию map или reduce в качестве источника истины :D, а также передаем вторым параметром функцию первого класса, которая собственно преобразует данные,  далее результат возвращается и присваивается другой переменной все епт  :D<br>
Другими словами исходные данные не меняются, создается новые измененые данные.<br>
- Маста а можно все тоже, но на примере?  :scratch:  <br>
Угу ща Новичок сообразимс&#33; :D<br>
- Подождем <br>
Уфф вот написал, тут я юзанул Select из Spring это аналог map:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;var strs := TCollections.CreateList&#60;string&#62;([</div><div class="code_line">&nbsp;&nbsp; &nbsp;&#39;grape&#39;, &#39;passionfruit&#39;, &#39;banana&#39;, &#39;mango&#39;,</div><div class="code_line">&nbsp;&nbsp; &nbsp;&#39;orange&#39;, &#39;raspberry&#39;, &#39;apple&#39;, &#39;blueberry&#39;</div><div class="code_line">&nbsp;&nbsp;]);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;var ints:= TEnumerable.Select&#60;string, integer&#62;(strs,</div><div class="code_line">&nbsp;&nbsp; &nbsp;function (s: string): integer</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Result:= Length(s);</div><div class="code_line">&nbsp;&nbsp; &nbsp;end</div><div class="code_line">&nbsp;&nbsp;);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// print</div><div class="code_line">&nbsp;&nbsp;for var i in ints do</div><div class="code_line">&nbsp;&nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp;Write(i, &#39;, &#39;);</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;&nbsp;// 5, 12, 6, 5, 6, 9, 5, 9,</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; Writeln;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;for var s in strs do</div><div class="code_line">&nbsp;&nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp;Write(s, &#39;, &#39;);</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;&nbsp;// grape, passionfruit, banana, mango, orange, raspberry, apple, blueberry,</div><div class="code_line">end.</div></ol></div></div></div></div><br>
Как видишь имеем два массива с разными данными.<br>
- Маста а что надо всегда менять тип данных?  :huh: <br>
Нет конешно можно не менять, например если нам надо удалить слово &quot;банан&quot;, то пишем следущее:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">var deletedBananas:= strs.Where(</div><div class="code_line">&nbsp;&nbsp; &nbsp;function (const s: string): Boolean</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;if s = &#39;banana&#39; then</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Result:= False</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;else</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Result:= True;</div><div class="code_line">&nbsp;&nbsp; &nbsp;end</div><div class="code_line">&nbsp;&nbsp;);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// print</div><div class="code_line">&nbsp;&nbsp;for var s in deletedBananas do</div><div class="code_line">&nbsp;&nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp;Write(s, &#39;, &#39;);</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;&nbsp;// grape, passionfruit, mango, orange, raspberry, apple, blueberry,</div></ol></div></div></div></div><br>
Тут я заюзал функцию Where тоже и Spring4D это аналог filter.<br>
- Ого начинаю понимать, а если нам надо удалить не банан, а passionfruit :D <br>
- Че нам опять все писать Where?  :huh: <br>
Зачем? Надо определить функцию и передавать туда значение которое надо удалить&#33; Давай напиши ее а я заценю.]]></description>
        <author>Cfon</author>
        <category>Delphi: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3795879</guid>
        <pubDate>Wed, 17 Apr 2019 12:36:22 +0000</pubDate>
        <title>Spring4D</title>
        <link>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3795879</link>
        <description><![CDATA[Cfon: Давайте сравним императивный подход с функциональным:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;&nbsp;// Императивный стиль</div><div class="code_line">&nbsp;&nbsp;var resultList: TArray&#60;TRecipeNameAndIngredientNames&#62;;</div><div class="code_line">&nbsp;&nbsp;for var recipe: TRecipe in recipes do</div><div class="code_line">&nbsp;&nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp;var listIngrNames: TArray&#60;string&#62;;</div><div class="code_line">&nbsp;&nbsp; &nbsp;for var ingr in recipe.Ingredients do</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;listIngrNames:= listIngrNames + [ingr.IngredientName];</div><div class="code_line">&nbsp;&nbsp; &nbsp;end;</div><div class="code_line">&nbsp;&nbsp; &nbsp;TArray.Sort&#60;string&#62;(listIngrNames);</div><div class="code_line">&nbsp;&nbsp; &nbsp;resultList:= resultList + [TRecipeNameAndIngredientNames.Create(recipe.RecipeName, listIngrNames)];</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// Функциональный </div><div class="code_line">&nbsp;&nbsp;const resultList = TEnumerable.Select&#60;TRecipe, TRecipeNameAndIngredientNames&#62;(recipes,</div><div class="code_line">&nbsp;&nbsp; &nbsp;function (recipe: TRecipe): TRecipeNameAndIngredientNames</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;const ingredientNames := TEnumerable.Select&#60;TIngredient, string&#62;(recipe.Ingredients,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;function (ingredient: TIngredient): string</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Result:= ingredient.IngredientName;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;end);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;const sorted:= TEnumerable.OrderBy&#60;string, string&#62;(ingredientNames,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;function (ingredientName: string): string</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Result:= ingredientName;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;end);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Result:= TRecipeNameAndIngredientNames.Create(recipe.RecipeName, IList&#60;string&#62;(sorted));</div><div class="code_line">&nbsp;&nbsp; &nbsp;end);</div></ol></div></div></div></div><br>
Как по мне императивный сложно сразу понять что он делает, особенно без комментов, а вот функциональный читается без коментов. Плас функц. имеет на один меньше цикл, у него цикл сортировки и селекта объединен в силу отложеного выполнения. Т.е. потенционально он будет быстрее при большом числе записей.<br>
Кроме того Функц. легко распарралелить, поскольку данные неизменяемы.<br>
Плас императивного он немного короче, хотя он короче чем на Делфи, в отношении C# сами видели не короче  :D]]></description>
        <author>Cfon</author>
        <category>Delphi: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3795801</guid>
        <pubDate>Tue, 16 Apr 2019 18:30:59 +0000</pubDate>
        <title>Spring4D</title>
        <link>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3795801</link>
        <description><![CDATA[Cfon: Ответ :D <br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">type</div><div class="code_line">&nbsp;&nbsp;TRecipeNameAndIngredientNames = record</div><div class="code_line">&nbsp;&nbsp; &nbsp;RecipeName: string;</div><div class="code_line">&nbsp;&nbsp; &nbsp;IngredientNames: IList&#60;string&#62;;</div><div class="code_line">&nbsp;&nbsp; &nbsp;constructor Create(ARecipeName: string; AIngredientNames: IList&#60;string&#62;);</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;</div><div class="code_line">{ TRecipeNameAndIngredientNames }</div><div class="code_line">&nbsp;</div><div class="code_line">constructor TRecipeNameAndIngredientNames.Create(ARecipeName: string;</div><div class="code_line">&nbsp;&nbsp;AIngredientNames: IList&#60;string&#62;);</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;RecipeName:= ARecipeName;</div><div class="code_line">&nbsp;&nbsp;IngredientNames:= AIngredientNames;</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;// load json file.</div><div class="code_line">&nbsp;&nbsp;var s:= TRecipesManager.LoadFile(TPath.Combine(</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;TPath.GetDocumentsPath, &#39;recipes.json&#39;));</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// create recipes list.</div><div class="code_line">&nbsp;&nbsp;var recipes: IList&#60;TRecipe&#62; := TRecipesManager.CreateRecipes(s);</div><div class="code_line">....</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;var query := TEnumerable.Select&#60;TRecipe, TRecipeNameAndIngredientNames&#62;(recipes,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;function (recipe: TRecipe): TRecipeNameAndIngredientNames</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;var ingredientNames := TEnumerable.Select&#60;TIngredient, string&#62;(</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;recipe.Ingredients,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;function (ingredient: TIngredient): string</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Result:= ingredient.IngredientName;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;end</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;var sorted:= TEnumerable.OrderBy&#60;string, string&#62;(ingredientNames,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;function (ingredientName: string): string</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Result:= ingredientName;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;end</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Result:= TRecipeNameAndIngredientNames.Create(recipe.RecipeName, IList&#60;string&#62;(sorted));</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;end</div><div class="code_line">&nbsp;&nbsp; &nbsp;);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// print the results.</div><div class="code_line">&nbsp;&nbsp;query.ForEach(procedure (const value: TRecipeNameAndIngredientNames)</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Writeln(value.RecipeName);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;value.IngredientNames.ForEach(procedure (const name: string)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Writeln(&#39; &nbsp; &nbsp;&#39;, name);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;end</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;);</div><div class="code_line">&nbsp;&nbsp; &nbsp;end</div><div class="code_line">&nbsp;&nbsp;); &nbsp;</div><div class="code_line">(*</div><div class="code_line">&nbsp;Baked Salmon</div><div class="code_line">&nbsp;&nbsp; &nbsp;Butter Lettuce</div><div class="code_line">&nbsp;&nbsp; &nbsp;Garlic</div><div class="code_line">&nbsp;&nbsp; &nbsp;Olive Oil</div><div class="code_line">&nbsp;&nbsp; &nbsp;Pine Nuts</div><div class="code_line">&nbsp;&nbsp; &nbsp;Salmon</div><div class="code_line">&nbsp;&nbsp; &nbsp;Yellow Squash</div><div class="code_line">Fish Tacos</div><div class="code_line">&nbsp;&nbsp; &nbsp;Cheese</div><div class="code_line">&nbsp;&nbsp; &nbsp;Iceberg Lettuce</div><div class="code_line">&nbsp;&nbsp; &nbsp;Tomatoes</div><div class="code_line">&nbsp;&nbsp; &nbsp;Tortillas</div><div class="code_line">&nbsp;&nbsp; &nbsp;Whitefish</div><div class="code_line">Checken Noodle Soup</div><div class="code_line">&nbsp;&nbsp; &nbsp;Carrots</div><div class="code_line">&nbsp;&nbsp; &nbsp;Celery</div><div class="code_line">&nbsp;&nbsp; &nbsp;Chiken Broth</div><div class="code_line">&nbsp;&nbsp; &nbsp;Cooked Chicken</div><div class="code_line">&nbsp;&nbsp; &nbsp;Extra-virgin olive oil</div><div class="code_line">&nbsp;&nbsp; &nbsp;Wide Egg Noodles</div><div class="code_line">&nbsp;&nbsp; &nbsp;Yello Onion</div><div class="code_line">*)</div><div class="code_line">end.</div></ol></div></div></div></div><br>
У кого возник тихий ужос? Понимаю&#33; :crazy: <br>
Тут нужна практика, это в основном из-за избыточного синтаксиса параметров генериков Делфи, в сравнении с JS или тем же C# это мягко говоря неудобно  :jokingly:<br>
<br>
Вот более удобоваримый код, тут просто вывод на консоль без создания списка, генериков тут нет и читать проще  :D <br>
Точнее генерики то есть параметризованые анонимки, нет угловых скобок  :D <br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">recipes.ForEach(procedure (const recipe: TRecipe)</div><div class="code_line">&nbsp;&nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp;Writeln(recipe.RecipeName);</div><div class="code_line">&nbsp;&nbsp; &nbsp;recipe.Ingredients.Ordered(</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;function(const Left, Right: TIngredient): Integer</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;if Left.IngredientName &#60; Right.IngredientName then</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Result:= -1</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;else if Left.IngredientName = Right.IngredientName then</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Result:= 0</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;else</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Result:= 1;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;end)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;.ForEach(procedure (const ingredient: TIngredient)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Writeln(&#39; &nbsp; &#39;, ingredient.IngredientName);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;end);</div><div class="code_line">&nbsp;&nbsp;end);</div></ol></div></div></div></div>]]></description>
        <author>Cfon</author>
        <category>Delphi: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3795765</guid>
        <pubDate>Tue, 16 Apr 2019 12:41:17 +0000</pubDate>
        <title>Spring4D</title>
        <link>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3795765</link>
        <description><![CDATA[Cfon: ОК. Задание&#33; <br>Надо попрактиковаться на примере, возьмем пример с рецептами. <br>Вывести данные в виде:<br>- название рецепта<br>-- список названий отсортированных инградиентов.]]></description>
        <author>Cfon</author>
        <category>Delphi: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3795751</guid>
        <pubDate>Tue, 16 Apr 2019 09:42:44 +0000</pubDate>
        <title>Spring4D</title>
        <link>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3795751</link>
        <description><![CDATA[Cfon: А вот и сюрприз&#33; Чекал OrderBy все путем полет нормальный, далее ThenBy и все тупик :D <br>
Короче объясняю OrderBy всем понятно сортировка, а вот ThenBy это дополнение к сортировке заданой OrderBy, т.е. например нам надо сортировать по длине строки и в алфавитном порядке, но в Spring делфи это не пашет&#33; Следущий пример сначало сортирует по длине строки, ну а потом в алфавитном порядке:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;var fruits := Enumerable&#60;string&#62;.Create([</div><div class="code_line">&nbsp;&nbsp; &nbsp;&#39;grape&#39;, &#39;passionfruit&#39;, &#39;banana&#39;, &#39;mango&#39;,</div><div class="code_line">&nbsp;&nbsp; &nbsp;&#39;orange&#39;, &#39;raspberry&#39;, &#39;apple&#39;, &#39;blueberry&#39;</div><div class="code_line">&nbsp;&nbsp;]);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// Sort the strings first by their length and then</div><div class="code_line">&nbsp;&nbsp;//alphabetically by passing the identity selector function.</div><div class="code_line">&nbsp;&nbsp;var query := fruits.OrderBy&#60;integer&#62;(</div><div class="code_line">&nbsp;&nbsp; &nbsp;function (fruit: string): integer</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Result:= Length(fruit);</div><div class="code_line">&nbsp;&nbsp; &nbsp;end</div><div class="code_line">&nbsp;&nbsp;);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;var query2:= Enumerable&#60;string&#62;.Create(query.ToArray)</div><div class="code_line">&nbsp;&nbsp; &nbsp;.ThenBy&#60;string&#62;(</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;function (fruit: string): string</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Result:= fruit;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;end</div><div class="code_line">&nbsp;&nbsp; &nbsp;);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;query2.ForEach(procedure (const fruit: string)</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Writeln(fruit);</div><div class="code_line">&nbsp;&nbsp; &nbsp;end</div><div class="code_line">&nbsp;&nbsp;);</div><div class="code_line">&nbsp;&nbsp;(* у меня output:</div><div class="code_line">&nbsp;&nbsp; &nbsp;apple</div><div class="code_line">&nbsp;&nbsp; &nbsp;banana</div><div class="code_line">&nbsp;&nbsp; &nbsp;blueberry</div><div class="code_line">&nbsp;&nbsp; &nbsp;grape</div><div class="code_line">&nbsp;&nbsp; &nbsp;mango</div><div class="code_line">&nbsp;&nbsp; &nbsp;orange</div><div class="code_line">&nbsp;&nbsp; &nbsp;passionfruit</div><div class="code_line">&nbsp;&nbsp; &nbsp;raspberry</div><div class="code_line">&nbsp;&nbsp;*)</div><div class="code_line">&nbsp;&nbsp;(* а надо:</div><div class="code_line">&nbsp;&nbsp; &nbsp;apple</div><div class="code_line">&nbsp;&nbsp; &nbsp;grape</div><div class="code_line">&nbsp;&nbsp; &nbsp;mango</div><div class="code_line">&nbsp;&nbsp; &nbsp;banana</div><div class="code_line">&nbsp;&nbsp; &nbsp;orange</div><div class="code_line">&nbsp;&nbsp; &nbsp;blueberry</div><div class="code_line">&nbsp;&nbsp; &nbsp;raspberry</div><div class="code_line">&nbsp;&nbsp; &nbsp;passionfruit</div><div class="code_line">&nbsp;&nbsp;*)</div><div class="code_line">end;</div><div class="code_line">(*C# code</div><div class="code_line">&nbsp;&nbsp;string[] fruits = { &quot;grape&quot;, &quot;passionfruit&quot;, &quot;banana&quot;, &quot;mango&quot;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&quot;orange&quot;, &quot;raspberry&quot;, &quot;apple&quot;, &quot;blueberry&quot; };</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// Sort the strings first by their length and then</div><div class="code_line">&nbsp;&nbsp;//alphabetically by passing the identity selector function.</div><div class="code_line">&nbsp;&nbsp;IEnumerable&#60;string&#62; query =</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;fruits.OrderBy(fruit =&#62; fruit.Length).ThenBy(fruit =&#62; fruit);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;foreach (string fruit in query)</div><div class="code_line">&nbsp;&nbsp;{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Console.WriteLine(fruit);</div><div class="code_line">&nbsp;&nbsp;}</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;/*</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;This code produces the following output:</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;apple</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;grape</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;mango</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;banana</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;orange</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;blueberry</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;raspberry</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;passionfruit</div><div class="code_line">&nbsp;&nbsp;*/*)</div></ol></div></div></div></div><br>
Я хз зачем тогда ваще нужен ThenBy  :wacko: <br>
<br>
<span class="tag-color tag-color-named" data-value="mergepost" style="color: mergepost"><span class='tag-size' data-value='7' style='font-size:7pt;'>Добавлено <time class="tag-mergetime" datetime="2019-04-16T10:38:37+00:00">16.04.19, 10:38</time></span></span><br>
Все понел в чем трабла :D <br>
Дело в том что в предыдущем примере имел место разрыв цепочки отложенного выполнения и вызов запроса сортировки через query.ToArray, следущий запрос query2 уже выполнял сортировку на уже отсортированых данных. <br>
Как я решил траблу? Все гениальное просто  :blush: определил функции ThenBy в классе TEnumerableHelper для TEnumerable и юзал их :D <br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">type</div><div class="code_line">&nbsp;&nbsp;TEnumerableHelper = class helper for TEnumerable</div><div class="code_line">&nbsp;&nbsp; &nbsp;...</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;class function ThenBy&#60;T, TKey&#62;(const source: IEnumerable&#60;T&#62;;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;const keySelector: TFunc&#60;T, TKey&#62;) : IEnumerable&#60;T&#62;; overload; static;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;class function ThenBy&#60;T, TKey&#62;(const source: IEnumerable&#60;T&#62;;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;const keySelector: TFunc&#60;T, TKey&#62;;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;const comparer: IComparer&#60;TKey&#62;): IEnumerable&#60;T&#62;; overload; static;</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;</div><div class="code_line">{ TEnumerableHelper }</div><div class="code_line">&nbsp;</div><div class="code_line">class function TEnumerableHelper.ThenBy&#60;T, TKey&#62;(const source: IEnumerable&#60;T&#62;;</div><div class="code_line">&nbsp;&nbsp;const keySelector: TFunc&#60;T, TKey&#62;;</div><div class="code_line">&nbsp;&nbsp;const comparer: IComparer&#60;TKey&#62;): IEnumerable&#60;T&#62;;</div><div class="code_line">begin</div><div class="code_line">// &nbsp;Guard.CheckNotNull(Assigned(source), &#39;source&#39;);</div><div class="code_line">// &nbsp;Guard.CheckNotNull(Assigned(keySelector), &#39;keySelector&#39;);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;Result := TOrderedEnumerable&#60;T, TKey&#62;.Create(source, keySelector, comparer, False);</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">class function TEnumerableHelper.ThenBy&#60;T, TKey&#62;(const source: IEnumerable&#60;T&#62;;</div><div class="code_line">&nbsp;&nbsp;const keySelector: TFunc&#60;T, TKey&#62;): IEnumerable&#60;T&#62;;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;Result := ThenBy&#60;T, TKey&#62;(source, keySelector, nil);</div><div class="code_line">end;</div></ol></div></div></div></div><br>
Теперь все пучком :dance: :hang:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;var fruits := TCollections.CreateList&#60;string&#62;([</div><div class="code_line">&nbsp;&nbsp; &nbsp;&#39;grape&#39;, &#39;passionfruit&#39;, &#39;banana&#39;, &#39;mango&#39;,</div><div class="code_line">&nbsp;&nbsp; &nbsp;&#39;orange&#39;, &#39;raspberry&#39;, &#39;apple&#39;, &#39;blueberry&#39;</div><div class="code_line">&nbsp;&nbsp;]);</div><div class="code_line">&nbsp;&nbsp;</div><div class="code_line">&nbsp;&nbsp;// Sort the strings first by their length and then</div><div class="code_line">&nbsp;&nbsp;//alphabetically by passing the identity selector function.</div><div class="code_line">&nbsp;&nbsp;var query := TEnumerable.OrderBy&#60;string, integer&#62;(fruits,</div><div class="code_line">&nbsp;&nbsp; &nbsp;function (fruit: string): integer</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Result:= Length(fruit);</div><div class="code_line">&nbsp;&nbsp; &nbsp;end</div><div class="code_line">&nbsp;&nbsp;);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// отложеное выполнение, ибо нет вызова query.ToArray</div><div class="code_line">&nbsp;&nbsp;var query2:= TEnumerable.ThenBy&#60;string, string&#62;(query, </div><div class="code_line">&nbsp;&nbsp; &nbsp;function (fruit: string): string</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Result:= fruit;</div><div class="code_line">&nbsp;&nbsp; &nbsp;end</div><div class="code_line">&nbsp;&nbsp;);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// а теперь сам запрос</div><div class="code_line">&nbsp;&nbsp;query2.ForEach(procedure (const fruit: string)</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Writeln(fruit);</div><div class="code_line">&nbsp;&nbsp; &nbsp;end</div><div class="code_line">&nbsp;&nbsp;); &nbsp;</div><div class="code_line">&nbsp;&nbsp;(*</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;apple</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;grape</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;mango</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;banana</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;orange</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;blueberry</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;raspberry</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;passionfruit</div><div class="code_line">&nbsp;&nbsp;*)</div><div class="code_line">end.</div></ol></div></div></div></div><br>
- Маста так а в чем проблема Enumerable&lt;T&gt;? Почему на TEnumerable пашет то?  :huh: <br>
Проблема в разрыве цепочки отложеного выполнения, Enumerable&lt;T&gt;.OrderBy возвращает IEnumerable&lt;T&gt; у которого нет ThenBy, но который есть в Enumerable&lt;T&gt;.<br>
А чтобы юзать Enumerable&lt;T&gt; надо снова его создать и передать предыдущий запрос, но поскольку в конструктор Enumerable&lt;T&gt; принимает тока динамический массив, а не ссылку на IEnumerable&lt;T&gt;, то надо копировать его через ToArray, что приводит к выполнению запроса и как следствие прерывание отложенного выполнения. Последующий запрос уже будет сортировать другие данные. Поэтому я определил в TEnumerableHelper ThenBy и передавал ему ссылку на IEnumerable&lt;T&gt;, что не прервало отложенного выполнения.  :D <br>
- Маста вы, вы, вы... ну... просто маста&#33; :jokingly: <br>
Думаешь?  :D  <br>
- Определено :jokingly: <br>
Ну ок :popcorn:<br>
<br>
- Маста это снова я&#33; А почему б не определить хелпер для Enumerable&lt;T&gt;?  :huh: <br>
Оуоу&#33; Не получится Enumerable&lt;T&gt; это генерик, а на генерики хелпер нельзя наложить.<br>
- А зачем ваще хелпер для TEnumerable? Можно просто создать функцию ThenBy.. :huh: <br>
Ну да можно, но мы ж пишем не гавнокод верно?  :D <br>
В Spring.Collections уже есть TEnumerable и в нем уже были определния некоторых функций из Enumerable&lt;T&gt;, вот я и добавляю еще через хелпер.<br>
Хотя стоп эти функции параметризованы, их нельзя создать вне класса или записи, поэтому надо по любому создавать отдельно класс или запись.<br>
<br>
ПС. Так я скоро на книжку напечатаю :lool:]]></description>
        <author>Cfon</author>
        <category>Delphi: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3795745</guid>
        <pubDate>Tue, 16 Apr 2019 07:43:25 +0000</pubDate>
        <title>Spring4D</title>
        <link>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3795745</link>
        <description><![CDATA[Cfon: <div class='tag-quote'><a class='tag-quote-link' href='https://forum.sources.ru/index.php?showtopic=414484&view=findpost&p=3795680'><span class='tag-quote-prefix'>Цитата</span></a> <span class='tag-quote__quote-info'>Cfon &#064; <time class="tag-quote__quoted-time" datetime="2019-04-15T12:39:46+00:00">15.04.19, 12:39</time></span><div class='quote '>Enumerable&lt;T&gt;.<strong class='tag-b'>ToDictionary</strong> - выполняет трансформацию массива в словарь. Тоже полезная вещь, ее кстати можно селектом зафигачить :D</div></div><br>
ошибочка не селектом, а агригейтом :D <br>
селект возварщает тот же тип контейнера его нельзя изменить, а вот агригейтом можно что угодно вернуть<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">// Create a Dictionary of Package objects,</div><div class="code_line">&nbsp;&nbsp;// using TrackingNumber as the key. </div><div class="code_line">&nbsp;&nbsp;// Result: &nbsp;IDictionary&#60;Uint64, TPackage&#62;</div><div class="code_line">&nbsp;&nbsp;var dictionary:= Packages.Aggregate&#60;IDictionary&#60;Uint64, TPackage&#62;&#62;(</div><div class="code_line">&nbsp;&nbsp; &nbsp;TCollections.CreateDictionary&#60;Uint64, TPackage&#62;,</div><div class="code_line">&nbsp;&nbsp; &nbsp;function (dict: IDictionary&#60;Uint64, TPackage&#62;; p: TPackage): IDictionary&#60;Uint64, TPackage&#62;</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;dict.Add(p.TrackingNumber, p);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Result:= dict;</div><div class="code_line">&nbsp;&nbsp; &nbsp;end</div><div class="code_line">&nbsp;&nbsp;);</div></ol></div></div></div></div> <br>
<br>
<span class="tag-color tag-color-named" data-value="mergepost" style="color: mergepost"><span class='tag-size' data-value='7' style='font-size:7pt;'>Добавлено <time class="tag-mergetime" datetime="2019-04-16T07:48:17+00:00">16.04.19, 07:48</time></span></span><br>
Пример со словарем функциональном стиле, тут мы определяем объект сразу по месту, а не в виде отдельного класса:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;// Result: IDictionary&#60;TBox, string&#62;</div><div class="code_line">&nbsp;&nbsp;var boxes:= TCollections.CreateDictionary&#60;TBox, string&#62;(</div><div class="code_line">&nbsp;&nbsp; &nbsp;TEqualityComparer&#60;TBox&#62;.Construct(</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;function(const Left, Right: TBox): Boolean</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;if &nbsp;Left = Right then</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Result:= True</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;else if (Left.Height = Right.Height) and</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(Left.Length = Right.Length) and</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(Left.Width = Right.Width) &nbsp;then</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Result:= True</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;else</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Result:= False;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;end,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;function(const Value: TBox): Integer</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Result:= Value.Height xor Value.Length xor Value.Width;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;end</div><div class="code_line">&nbsp;&nbsp; &nbsp;)</div><div class="code_line">&nbsp;&nbsp;);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;var redBox:= TBox.Create(4,3,4);</div><div class="code_line">&nbsp;&nbsp;TBoxManager.AddBox(boxes, redBox, &#39;red&#39;);</div><div class="code_line">&nbsp;&nbsp;TBoxManager.AddBox(boxes, redBox, &#39;red2&#39;);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;var blueBox:= TBox.Create(4,3,4);</div><div class="code_line">&nbsp;&nbsp;TBoxManager.AddBox(boxes, blueBox, &#39;blue&#39;);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;var greenBox:= TBox.Create(3,4,3);</div><div class="code_line">&nbsp;&nbsp;TBoxManager.AddBox(boxes, greenBox, &#39;green&#39;);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;Writeln;</div><div class="code_line">&nbsp;&nbsp;Writeln(Format(&#39;The dictionary contains %d Box objects.&#39;, [boxes.Count]));</div><div class="code_line">end;</div><div class="code_line">// The example displays the following output:</div><div class="code_line">// &nbsp; &nbsp;Unable to add (4, 3, 4): Duplicates not allowed</div><div class="code_line">// &nbsp; &nbsp;Unable to add (4, 3, 4): Duplicates not allowed</div><div class="code_line">//</div><div class="code_line">// &nbsp; &nbsp;The dictionary contains 2 Box objects.</div></ol></div></div></div></div><br>
Замечу что надо отдельно удалять объекты TBox, их словарь не чистит. <br>
<br>
<span class="tag-color tag-color-named" data-value="mergepost" style="color: mergepost"><span class='tag-size' data-value='7' style='font-size:7pt;'>Добавлено <time class="tag-mergetime" datetime="2019-04-16T08:11:39+00:00">16.04.19, 08:11</time></span></span><br>
<div class='tag-quote'><a class='tag-quote-link' href='https://forum.sources.ru/index.php?showtopic=414484&view=findpost&p=3795695'><span class='tag-quote-prefix'>Цитата</span></a> <span class='tag-quote__quote-info'>Cfon &#064; <time class="tag-quote__quoted-time" datetime="2019-04-15T16:30:45+00:00">15.04.19, 16:30</time></span><div class='quote '>Да если скорость добавления объектов в словарь критична, то в TBoxEqualityComparer.Equals можно добавить в начало проверку адресов объектов.<br>
Думаю на 100 тыщах будет заметен эффект  :D</div></div><br>
Оуоу.. неа, тока если одинаковых объектов будет много, например, 50%  :D <br>
Почему? Потому шо сравнитель запускает проверку на equals тока если хешер вернет одинаковое значение для двух объектов. Поэтому время выполнения вставки данных зависит от скорости хешера, а не от проверки на идентичность.]]></description>
        <author>Cfon</author>
        <category>Delphi: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3795695</guid>
        <pubDate>Mon, 15 Apr 2019 16:30:45 +0000</pubDate>
        <title>Spring4D</title>
        <link>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3795695</link>
        <description><![CDATA[Cfon: еще два вызова ToDictionary, первый в качестве значения добавляет строку, а не запись TPackage, а второй юзает дефолтный сравниватель, что по идее является вариантом первого вызова  :D <br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">...</div><div class="code_line">&nbsp;&nbsp;// Result: IDictionary&#60;UInt64, STRING&#62;</div><div class="code_line">&nbsp;&nbsp;var dictionary := Packages.ToDictionary&#60;UInt64, STRING&#62;(</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;function (p: TPackage): UInt64</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Result:= p.TrackingNumber;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;end,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;function (p: TPackage): STRING</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Result:= p.Company;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;end</div><div class="code_line">&nbsp;&nbsp;);</div><div class="code_line">....</div></ol></div></div></div></div><br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">...</div><div class="code_line">&nbsp;&nbsp;// Result: IDictionary&#60;UInt64, TPackage&#62;</div><div class="code_line">&nbsp;&nbsp;var dictionary := Packages.ToDictionary&#60;UInt64&#62;(</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;function (p: TPackage): UInt64</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Result:= p.TrackingNumber;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;end,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;TEqualityComparer&#60;UInt64&#62;.Default</div><div class="code_line">&nbsp;&nbsp;);</div><div class="code_line">...</div></ol></div></div></div></div> <br>
<br>
<span class="tag-color tag-color-named" data-value="mergepost" style="color: mergepost"><span class='tag-size' data-value='7' style='font-size:7pt;'>Добавлено <time class="tag-mergetime" datetime="2019-04-15T16:42:34+00:00">15.04.19, 16:42</time></span></span><br>
Пример со словарем IDictionary&lt;TKey, TValue&gt;<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">uses</div><div class="code_line">&nbsp;&nbsp;System.SysUtils,</div><div class="code_line">&nbsp;&nbsp;System.Generics.Defaults,</div><div class="code_line">&nbsp;&nbsp;Spring.Collections;</div><div class="code_line">&nbsp;</div><div class="code_line">type</div><div class="code_line">&nbsp;&nbsp;TBox = class</div><div class="code_line">&nbsp;&nbsp; &nbsp;Height: integer;</div><div class="code_line">&nbsp;&nbsp; &nbsp;Width: integer;</div><div class="code_line">&nbsp;&nbsp; &nbsp;Length: integer;</div><div class="code_line">&nbsp;&nbsp; &nbsp;constructor Create(AHeight, ALength, AWidth: integer);</div><div class="code_line">&nbsp;&nbsp; &nbsp;function ToString: string; override;</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;TBoxEqualityComparer = class(TInterfacedObject, IEqualityComparer&#60;TBox&#62;)</div><div class="code_line">&nbsp;&nbsp; &nbsp;function Equals(const Left, Right: TBox): Boolean; reintroduce;</div><div class="code_line">&nbsp;&nbsp; &nbsp;function GetHashCode(const Value: TBox): Integer; reintroduce;</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;TBoxManager = record</div><div class="code_line">&nbsp;&nbsp; &nbsp;class procedure AddBox(dict: IDictionary&#60;TBox, String&#62;; box: TBox; name: string); static;</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;</div><div class="code_line">{ TBox }</div><div class="code_line">&nbsp;</div><div class="code_line">constructor TBox.Create(AHeight, ALength, AWidth: integer);</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;Height := AHeight;</div><div class="code_line">&nbsp;&nbsp;Length := ALength;</div><div class="code_line">&nbsp;&nbsp;Width := AWidth;</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">function TBox.ToString: string;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;Result:= Format(&#39;(%d, %d, %d)&#39;, [Height, Length, Width]);</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">{ TBoxEqualityComparer }</div><div class="code_line">&nbsp;</div><div class="code_line">function TBoxEqualityComparer.Equals(const Left, Right: TBox): Boolean;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp; if (Left.Height = Right.Height)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;and (Left.Length = Right.Length)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;and (Left.Width = Right.Width) &nbsp;then</div><div class="code_line">&nbsp;&nbsp; &nbsp;Result:= True</div><div class="code_line">&nbsp;&nbsp;else</div><div class="code_line">&nbsp;&nbsp; &nbsp;Result:= False;</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">function TBoxEqualityComparer.GetHashCode(const Value: TBox): Integer;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;var hCode := Value.Height xor Value.Length xor Value.Width;</div><div class="code_line">&nbsp;&nbsp;Result:= hCode;</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">{ TBoxManager }</div><div class="code_line">&nbsp;</div><div class="code_line">class procedure TBoxManager.AddBox(dict: IDictionary&#60;TBox, String&#62;; box: TBox;</div><div class="code_line">&nbsp;&nbsp;name: string);</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;try</div><div class="code_line">&nbsp;&nbsp; &nbsp;dict.Add(box, name);</div><div class="code_line">&nbsp;&nbsp;except</div><div class="code_line">&nbsp;&nbsp; &nbsp;on E: EListError do</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;WriteLn(Format(&#39;Unable to add %s: %s&#39;, [box.ToString, E.Message]));</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">{ DictionaryExample }</div><div class="code_line">&nbsp;</div><div class="code_line">procedure DictionaryExample;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;var comparer:= TBoxEqualityComparer.Create;</div><div class="code_line">&nbsp;&nbsp;var boxes:= TCollections.CreateDictionary&#60;TBox, string&#62;(</div><div class="code_line">&nbsp;&nbsp; &nbsp;comparer</div><div class="code_line">// TEqualityComparer&#60;TBox&#62;.Default</div><div class="code_line">&nbsp;&nbsp;);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;var redBox:= TBox.Create(4,3,4);</div><div class="code_line">&nbsp;&nbsp;TBoxManager.AddBox(boxes, redBox, &#39;red&#39;);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;var blueBox:= TBox.Create(4,3,4);</div><div class="code_line">&nbsp;&nbsp;TBoxManager.AddBox(boxes, blueBox, &#39;blue&#39;);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;var greenBox:= TBox.Create(3,4,3);</div><div class="code_line">&nbsp;&nbsp;TBoxManager.AddBox(boxes, greenBox, &#39;green&#39;);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;Writeln;</div><div class="code_line">&nbsp;&nbsp;Writeln(Format(&#39;The dictionary contains %d Box objects.&#39;, [boxes.Count]));</div><div class="code_line">end;</div><div class="code_line">// The example displays the following output:</div><div class="code_line">// &nbsp; &nbsp;Unable to add (4, 3, 4): Duplicates not allowed</div><div class="code_line">//</div><div class="code_line">// &nbsp; &nbsp;The dictionary contains 2 Box objects.</div><div class="code_line">&nbsp;</div><div class="code_line">end.</div></ol></div></div></div></div><br>
Тут дефолтный сравнитель не катит, ибо он сравнивает адреса объектов TBox, поэтому пишем кастомный сравнитель.<br>
Если же заменить класс TBox на запись, то дефотный прокатит.<br>
Да если скорость добавления объектов в словарь критична, то в TBoxEqualityComparer.Equals можно добавить в начало проверку адресов объектов.<br>
Думаю на 100 тыщах будет заметен эффект  :D]]></description>
        <author>Cfon</author>
        <category>Delphi: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3795680</guid>
        <pubDate>Mon, 15 Apr 2019 12:39:46 +0000</pubDate>
        <title>Spring4D</title>
        <link>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3795680</link>
        <description><![CDATA[Cfon: Enumerable&lt;T&gt;.<strong class='tag-b'>ToDictionary</strong> - выполняет трансформацию массива в словарь. Тоже полезная вещь, ее кстати можно селектом зафигачить :D <br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">uses</div><div class="code_line">&nbsp;&nbsp;System.SysUtils,</div><div class="code_line">&nbsp;&nbsp;Spring.Collections,</div><div class="code_line">&nbsp;&nbsp;Spring.Collections.Enumerable;</div><div class="code_line">&nbsp;</div><div class="code_line">type</div><div class="code_line">&nbsp;&nbsp;TPackage = record</div><div class="code_line">&nbsp;&nbsp; &nbsp;Company: string;</div><div class="code_line">&nbsp;&nbsp; &nbsp;Weight: double;</div><div class="code_line">&nbsp;&nbsp; &nbsp;TrackingNumber: uint64;</div><div class="code_line">&nbsp;&nbsp; &nbsp;constructor Create(ACompany: string; AWeight: double; ATrackingNumber: uint64);</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;</div><div class="code_line">{ TPackage }</div><div class="code_line">&nbsp;</div><div class="code_line">constructor TPackage.Create(ACompany: string; AWeight: double;</div><div class="code_line">&nbsp;&nbsp;ATrackingNumber: uint64);</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;Company:= ACompany;</div><div class="code_line">&nbsp;&nbsp;Weight:= AWeight;</div><div class="code_line">&nbsp;&nbsp;TrackingNumber:= ATrackingNumber;</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;// Create a list of Packages.</div><div class="code_line">&nbsp;&nbsp;var Packages := Enumerable&#60;TPackage&#62;.Create([</div><div class="code_line">&nbsp;&nbsp; &nbsp;TPackage.Create(&#39;Coho Vineyard&#39;, 25.2, 89453312),</div><div class="code_line">&nbsp;&nbsp; &nbsp;TPackage.Create(&#39;Lucerne Publishing&#39;, 18.7, 89112755),</div><div class="code_line">&nbsp;&nbsp; &nbsp;TPackage.Create(&#39;Wingtip Toys&#39;, 6.0, 299456122),</div><div class="code_line">&nbsp;&nbsp; &nbsp;TPackage.Create(&#39;Adventure Works&#39;, 33.8, 4665518773)</div><div class="code_line">&nbsp;&nbsp;]);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// Create a Dictionary of Package objects,</div><div class="code_line">&nbsp;&nbsp;// using TrackingNumber as the key.</div><div class="code_line">&nbsp;&nbsp;var dictionary:= Packages.ToDictionary&#60;UInt64&#62;(</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;function (p: TPackage): UInt64</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Result:= p.TrackingNumber;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;end</div><div class="code_line">&nbsp;&nbsp;);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;for var kvp in dictionary do</div><div class="code_line">&nbsp;&nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp;Writeln(Format(&#39;Key %d: %s, %f pounds&#39;, [</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;kvp.Key, kvp.Value.Company, kvp.Value.Weight]));</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">end.</div><div class="code_line">(*C# code</div><div class="code_line">&nbsp;&nbsp;List&#60;Package&#62; packages =</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;new List&#60;Package&#62;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{ new Package { Company = &quot;Coho Vineyard&quot;, Weight = 25.2, TrackingNumber = 89453312L },</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;new Package { Company = &quot;Lucerne Publishing&quot;, Weight = 18.7, TrackingNumber = 89112755L },</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;new Package { Company = &quot;Wingtip Toys&quot;, Weight = 6.0, TrackingNumber = 299456122L },</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;new Package { Company = &quot;Adventure Works&quot;, Weight = 33.8, TrackingNumber = 4665518773L } };</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;// Create a Dictionary of Package objects,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;// using TrackingNumber as the key.</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Dictionary&#60;long, Package&#62; dictionary =</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;packages.ToDictionary(p =&#62; p.TrackingNumber);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;foreach (KeyValuePair&#60;long, Package&#62; kvp in dictionary)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Console.WriteLine(</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&quot;Key {0}: {1}, {2} pounds&quot;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;kvp.Key,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;kvp.Value.Company,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;kvp.Value.Weight);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;}</div><div class="code_line">&nbsp;&nbsp;}</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;/*</div><div class="code_line">&nbsp;&nbsp; This code produces the following output:</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; Key 89453312: Coho Vineyard, 25.2 pounds</div><div class="code_line">&nbsp;&nbsp; Key 89112755: Lucerne Publishing, 18.7 pounds</div><div class="code_line">&nbsp;&nbsp; Key 299456122: Wingtip Toys, 6 pounds</div><div class="code_line">&nbsp;&nbsp; Key 4665518773: Adventure Works, 33.8 pounds</div><div class="code_line">&nbsp;&nbsp;*/*)</div></ol></div></div></div></div><br>
<br>
Кстати изучая Enumerable&lt;T&gt; обнаружил что у него есть метод Concat так что можно добавить данные и тут, хотя скорее не добавить, а создать новый Enumerable&lt;T&gt;, ибо Concat не изменяет массив как IList.Add:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">var Packages2: Enumerable&#60;TPackage&#62;;</div><div class="code_line">&nbsp;&nbsp;Packages2:= Packages.Concat([TPackage.Create(&#39;Contoso Pharmaceuticals&#39;, 9.3, 670053128)]);</div></ol></div></div></div></div><br>
вот так не пашет, точнее пашет но тип получается IEnumerable&lt;TPackage&gt;:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">var Packages2:= Packages.Concat([TPackage.Create(&#39;Contoso Pharmaceuticals&#39;, 9.3, 670053128)]);</div></ol></div></div></div></div><br>
надо кастить<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">var Packages2:= Enumerable&#60;TPackage&#62;(Packages.Concat([TPackage.Create(&#39;Contoso Pharmaceuticals&#39;, 9.3, 670053128)]));</div></ol></div></div></div></div><br>
ну или так<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">Packages := Packages.Concat([TPackage.Create(&#39;Contoso Pharmaceuticals&#39;, 9.3, 670053128)]);</div></ol></div></div></div></div><br>
но это не в духе функционального прогинга, но кто запретит :D<br>
Думаю если это не будет привычкой, то все можно если осторожно :rake:]]></description>
        <author>Cfon</author>
        <category>Delphi: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3795606</guid>
        <pubDate>Sun, 14 Apr 2019 18:33:35 +0000</pubDate>
        <title>Spring4D</title>
        <link>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3795606</link>
        <description><![CDATA[Cfon: Enumerable&lt;T&gt;.<strong class='tag-b'>ToLookup</strong> весьма интересная функция группировки данных, пришлось снова заюзать Enumerable по причине отсутчвия реализации в TEnumerable :D<br>
Не самая сложная в переводе, возможно по причине уже набитости руки  :blush: <br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">uses</div><div class="code_line">&nbsp;&nbsp;System.SysUtils,</div><div class="code_line">&nbsp;&nbsp;Spring.Collections,</div><div class="code_line">&nbsp;&nbsp;Spring.Collections.Enumerable;</div><div class="code_line">&nbsp;</div><div class="code_line">type</div><div class="code_line">&nbsp;&nbsp;TPackage = record</div><div class="code_line">&nbsp;&nbsp; &nbsp;Company: string;</div><div class="code_line">&nbsp;&nbsp; &nbsp;Weight: double;</div><div class="code_line">&nbsp;&nbsp; &nbsp;TrackingNumber: uint64;</div><div class="code_line">&nbsp;&nbsp; &nbsp;constructor Create(ACompany: string; AWeight: double; ATrackingNumber: uint64);</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;</div><div class="code_line">{ TPackage }</div><div class="code_line">&nbsp;</div><div class="code_line">constructor TPackage.Create(ACompany: string; AWeight: double;</div><div class="code_line">&nbsp;&nbsp;ATrackingNumber: uint64);</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;Company:= ACompany;</div><div class="code_line">&nbsp;&nbsp;Weight:= AWeight;</div><div class="code_line">&nbsp;&nbsp;TrackingNumber:= ATrackingNumber;</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;// Create a list of Packages.</div><div class="code_line">&nbsp;&nbsp;var Packages := TCollections.CreateList&#60;TPackage&#62;([</div><div class="code_line">&nbsp;&nbsp; &nbsp;TPackage.Create(&#39;Coho Vineyard&#39;, 25.2, 89453312),</div><div class="code_line">&nbsp;&nbsp; &nbsp;TPackage.Create(&#39;Lucerne Publishing&#39;, 18.7, 89112755),</div><div class="code_line">&nbsp;&nbsp; &nbsp;TPackage.Create(&#39;Wingtip Toys&#39;, 6.0, 299456122),</div><div class="code_line">&nbsp;&nbsp; &nbsp;TPackage.Create(&#39;Contoso Pharmaceuticals&#39;, 9.3, 670053128),</div><div class="code_line">&nbsp;&nbsp; &nbsp;TPackage.Create(&#39;Wide World Importers&#39;, 33.8, 4665518773)</div><div class="code_line">&nbsp;&nbsp;]);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// Create a Lookup to organize the packages.</div><div class="code_line">&nbsp;&nbsp;// Use the first character of Company as the key value.</div><div class="code_line">&nbsp;&nbsp;// Select Company appended to TrackingNumber</div><div class="code_line">&nbsp;&nbsp;// as the element values of the Lookup.</div><div class="code_line">&nbsp;&nbsp;var lookup := Enumerable&#60;TPackage&#62;.Create(Packages.ToArray)</div><div class="code_line">&nbsp;&nbsp; &nbsp;.ToLookup&#60;Char, string&#62;(</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;function (p: TPackage): Char</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Result:= p.Company.Substring(0, 1)[1];</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;end,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;function (p: TPackage): string</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Result:= p.Company + &#39; &#39; + p.TrackingNumber.ToString;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;end</div><div class="code_line">&nbsp;&nbsp; &nbsp;);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;// Iterate through each IGrouping in the Lookup.</div><div class="code_line">&nbsp;&nbsp; &nbsp;for var packageGroup in lookup do</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;// Print the key value of the IGrouping.</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Writeln(packageGroup.Key);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;// Iterate through each value in the</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;// IGrouping and print its value.</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;for var str in packageGroup do</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Writeln(&#39; &nbsp; &nbsp;&#39;, str);</div><div class="code_line">&nbsp;&nbsp; &nbsp;end;</div><div class="code_line">end;</div><div class="code_line">(* C# code</div><div class="code_line">// Create a list of Packages.</div><div class="code_line">&nbsp;&nbsp; &nbsp;List&#60;Package&#62; packages =</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;new List&#60;Package&#62;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{ new Package { Company = &quot;Coho Vineyard&quot;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Weight = 25.2, TrackingNumber = 89453312L },</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;new Package { Company = &quot;Lucerne Publishing&quot;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Weight = 18.7, TrackingNumber = 89112755L },</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;new Package { Company = &quot;Wingtip Toys&quot;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Weight = 6.0, TrackingNumber = 299456122L },</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;new Package { Company = &quot;Contoso Pharmaceuticals&quot;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Weight = 9.3, TrackingNumber = 670053128L },</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;new Package { Company = &quot;Wide World Importers&quot;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Weight = 33.8, TrackingNumber = 4665518773L } };</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;// Create a Lookup to organize the packages.</div><div class="code_line">&nbsp;&nbsp; &nbsp;// Use the first character of Company as the key value.</div><div class="code_line">&nbsp;&nbsp; &nbsp;// Select Company appended to TrackingNumber</div><div class="code_line">&nbsp;&nbsp; &nbsp;// as the element values of the Lookup.</div><div class="code_line">&nbsp;&nbsp; &nbsp;ILookup&#60;char, string&#62; lookup =</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;packages</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;.ToLookup(p =&#62; Convert.ToChar(p.Company.Substring(0, 1)),</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;p =&#62; p.Company + &quot; &quot; + p.TrackingNumber);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;// Iterate through each IGrouping in the Lookup.</div><div class="code_line">&nbsp;&nbsp; &nbsp;foreach (IGrouping&#60;char, string&#62; packageGroup in lookup)</div><div class="code_line">&nbsp;&nbsp; &nbsp;{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;// Print the key value of the IGrouping.</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Console.WriteLine(packageGroup.Key);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;// Iterate through each value in the</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;// IGrouping and print its value.</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;foreach (string str in packageGroup)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Console.WriteLine(&quot; &nbsp; &nbsp;{0}&quot;, str);</div><div class="code_line">&nbsp;&nbsp; &nbsp;}</div><div class="code_line">}</div><div class="code_line">&nbsp;</div><div class="code_line">/*</div><div class="code_line">&nbsp;This code produces the following output:</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;C</div><div class="code_line">&nbsp;&nbsp; &nbsp; Coho Vineyard 89453312</div><div class="code_line">&nbsp;&nbsp; &nbsp; Contoso Pharmaceuticals 670053128</div><div class="code_line">&nbsp;L</div><div class="code_line">&nbsp;&nbsp; &nbsp; Lucerne Publishing 89112755</div><div class="code_line">&nbsp;W</div><div class="code_line">&nbsp;&nbsp; &nbsp; Wingtip Toys 299456122</div><div class="code_line">&nbsp;&nbsp; &nbsp; Wide World Importers 4665518773</div><div class="code_line">*/*)</div><div class="code_line">end.</div></ol></div></div></div></div>]]></description>
        <author>Cfon</author>
        <category>Delphi: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3795593</guid>
        <pubDate>Sun, 14 Apr 2019 16:54:40 +0000</pubDate>
        <title>Spring4D</title>
        <link>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3795593</link>
        <description><![CDATA[Cfon: <div class='tag-quote'><a class='tag-quote-link' href='https://forum.sources.ru/index.php?showtopic=414484&view=findpost&p=3795580'><span class='tag-quote-prefix'>Цитата</span></a> <span class='tag-quote__quote-info'>Cfon &#064; <time class="tag-quote__quoted-time" datetime="2019-04-14T12:30:53+00:00">14.04.19, 12:30</time></span><div class='quote '>Тест произодительности Spring4D vs простой цикл :D <br>
тестил на массиве из ~2000 слов, Spring4D Distint быстрее обычного цикла  :blink: <br>
В чем я ошибся или у меня массив не правильный?  :D </div></div><br>
Все понел&#33;  :D <br>
Дело в том что Spring Distinct юзает хешсет для создания уникального списка слов, т.е он фастом в один проход создает список, а в примере на цикле идет два цикла, один на добавление другой на поиск совпадения, что естесно ведет к низкой производительности. Как то так  :D]]></description>
        <author>Cfon</author>
        <category>Delphi: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3795580</guid>
        <pubDate>Sun, 14 Apr 2019 12:30:53 +0000</pubDate>
        <title>Spring4D</title>
        <link>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3795580</link>
        <description><![CDATA[Cfon: IEnumerable&lt;T&gt;.<strong class='tag-b'>Max</strong><br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">uses</div><div class="code_line">&nbsp;&nbsp;Spring.Collections;</div><div class="code_line">&nbsp;</div><div class="code_line">type</div><div class="code_line">&nbsp;&nbsp;TPet = record</div><div class="code_line">&nbsp;&nbsp; &nbsp;Name: string;</div><div class="code_line">&nbsp;&nbsp; &nbsp;Age: integer;</div><div class="code_line">&nbsp;&nbsp; &nbsp;constructor Create(AName: string; AAge: integer);</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;</div><div class="code_line">{ TPet }</div><div class="code_line">&nbsp;</div><div class="code_line">constructor TPet.Create(AName: string; AAge: integer);</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;Name:= AName; Age:=AAge;</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;var Ints: IList&#60;integer&#62;:= TCollections.CreateList&#60;integer&#62;([1,2,3,4,5]);</div><div class="code_line">&nbsp;&nbsp;var maxInt:= Ints.Max;</div><div class="code_line">&nbsp;&nbsp;Writeln(maxInt);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;var Pets: IList&#60;TPet&#62;:= TCollections.CreateList&#60;TPet&#62;([</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;TPet.Create(&#39;Barley&#39;, 8),</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;TPet.Create(&#39;Boots&#39;, 4),</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;TPet.Create(&#39;Whiskers&#39;, 1)</div><div class="code_line">&nbsp;&nbsp;]);</div><div class="code_line">&nbsp;&nbsp;</div><div class="code_line">&nbsp;&nbsp;var max: integer:= Pets.Max(function ( pet: TPet): integer</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Result:= pet.Age + Length(pet.Name);</div><div class="code_line">&nbsp;&nbsp; &nbsp;end</div><div class="code_line">&nbsp;&nbsp;);</div><div class="code_line">&nbsp;&nbsp;Writeln(max);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;Readln;</div><div class="code_line">end.</div><div class="code_line">(*C# code</div><div class="code_line">&nbsp;&nbsp;Pet[] pets = { new Pet { Name=&quot;Barley&quot;, Age=8 },</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; new Pet { Name=&quot;Boots&quot;, Age=4 },</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; new Pet { Name=&quot;Whiskers&quot;, Age=1 } };</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;int max = pets.Max(pet =&#62; pet.Age + pet.Name.Length);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Console.WriteLine(</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&quot;The maximum pet age plus name length is {0}.&quot;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;max);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;/*</div><div class="code_line">&nbsp;&nbsp; This code produces the following output:</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; The maximum pet age plus name length is 14.</div><div class="code_line">&nbsp;&nbsp;*/</div><div class="code_line">*)</div></ol></div></div></div></div><br>
Вот немного сложнее<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">...</div><div class="code_line">&nbsp;&nbsp;TPetComparer = class(TComparer&#60;TPet&#62;)</div><div class="code_line">&nbsp;&nbsp; &nbsp;function Compare(const Left, Right: TPet): Integer; override;</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;</div><div class="code_line">{ TPetComparer }</div><div class="code_line">&nbsp;</div><div class="code_line">function TPetComparer.Compare(const Left, Right: TPet): Integer;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;var sumLeft:= Left.Age + Length(Left.Name);</div><div class="code_line">&nbsp;&nbsp;var sumRight:= Right.Age + Length(Right.Name);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;if sumLeft &#60; sumRight then</div><div class="code_line">&nbsp;&nbsp; &nbsp;Result:= -1</div><div class="code_line">&nbsp;&nbsp;else if sumLeft = sumRight then</div><div class="code_line">&nbsp;&nbsp; &nbsp;Result:= 0</div><div class="code_line">&nbsp;&nbsp;else</div><div class="code_line">&nbsp;&nbsp; &nbsp;Result:= 1;</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;var Pets: IList&#60;TPet&#62;:= TCollections.CreateList&#60;TPet&#62;([</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;TPet.Create(&#39;Barley&#39;, 8),</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;TPet.Create(&#39;Boots&#39;, 4),</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;TPet.Create(&#39;Whiskers&#39;, 1)</div><div class="code_line">&nbsp;&nbsp;]);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// comparer: &nbsp;TComparison&#60;T&#62;</div><div class="code_line">&nbsp;&nbsp;var max: TPet:= Pets.Max(function (const Left, Right: TPet): integer</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;var sumLeft:= Left.Age + Length(Left.Name);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;var sumRight:= Right.Age + Length(Right.Name);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;if sumLeft &#60; sumRight then</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Result:= -1</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;else if sumLeft = sumRight then</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Result:= 0</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;else</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Result:= 1;</div><div class="code_line">&nbsp;&nbsp; &nbsp;end</div><div class="code_line">&nbsp;&nbsp;);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;Writeln(&#39;The &quot;maximum&quot; animal is &#39;, max.Name);</div><div class="code_line">&nbsp;&nbsp;// The &quot;maximum&quot; animal is Barley.</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// ну или через IComparer&#60;T&#62;</div><div class="code_line">&nbsp;&nbsp;var comparer: IComparer&#60;TPet&#62;:= TPetComparer.Create;</div><div class="code_line">&nbsp;&nbsp;var max: TPet:= Pets.Max(comparer);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;Writeln(&#39;The &quot;maximum&quot; animal is &#39;, max.Name);</div><div class="code_line">&nbsp;&nbsp;// The &quot;maximum&quot; animal is Barley. &nbsp;</div><div class="code_line">end.</div><div class="code_line">(* C# code</div><div class="code_line">/// &#60;summary&#62;</div><div class="code_line">&nbsp;&nbsp;/// This class implements IComparable to be able to</div><div class="code_line">&nbsp;&nbsp;/// compare one Pet to another Pet.</div><div class="code_line">&nbsp;&nbsp;/// &#60;/summary&#62;</div><div class="code_line">&nbsp;&nbsp;class Pet : IComparable&#60;Pet&#62;</div><div class="code_line">&nbsp;&nbsp;{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;public string Name { get; set; }</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;public int Age { get; set; }</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;/// &#60;summary&#62;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;/// Compares this Pet to another Pet by</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;/// summing each Pet&#39;s age and name length.</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;/// &#60;/summary&#62;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;/// &#60;param name=&quot;other&quot;&#62;The Pet to compare this Pet to.&#60;/param&#62;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;/// &#60;returns&#62;-1 if this Pet is &#39;less&#39; than the other Pet,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;/// 0 if they are equal,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;/// or 1 if this Pet is &#39;greater&#39; than the other Pet.&#60;/returns&#62;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;int IComparable&#60;Pet&#62;.CompareTo(Pet other)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;int sumOther = other.Age + other.Name.Length;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;int sumThis = this.Age + this.Name.Length;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if (sumOther &#62; sumThis)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return -1;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;else if (sumOther == sumThis)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return 0;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;else</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return 1;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;}</div><div class="code_line">&nbsp;&nbsp;}</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;public static void MaxEx3()</div><div class="code_line">&nbsp;&nbsp;{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Pet[] pets = { new Pet { Name=&quot;Barley&quot;, Age=8 },</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; new Pet { Name=&quot;Boots&quot;, Age=4 },</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; new Pet { Name=&quot;Whiskers&quot;, Age=1 } };</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Pet max = pets.Max();</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Console.WriteLine(</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&quot;The &#39;maximum&#39; animal is {0}.&quot;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;max.Name);</div><div class="code_line">&nbsp;&nbsp;}</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;/*</div><div class="code_line">&nbsp;&nbsp; This code produces the following output:</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; The &#39;maximum&#39; animal is Barley.</div><div class="code_line">&nbsp;&nbsp;*/*)</div></ol></div></div></div></div><br>
Шарповый пример показан на IComparable, с ним Spring4D не работает. <br>
<br>
<span class="tag-color tag-color-named" data-value="mergepost" style="color: mergepost"><span class='tag-size' data-value='7' style='font-size:7pt;'>Добавлено <time class="tag-mergetime" datetime="2019-04-14T13:21:18+00:00">14.04.19, 13:21</time></span></span><br>
Тест произодительности Spring4D vs простой цикл :D <br>
тестил на массиве из ~2000 слов, Spring4D Distint быстрее обычного цикла  :blink: <br>
В чем я ошибся или у меня массив не правильный?  :D <br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">uses</div><div class="code_line">&nbsp;&nbsp;System.Classes, System.SysUtils, System.Diagnostics, System.IOUtils,</div><div class="code_line">&nbsp;&nbsp;Spring.Collections;</div><div class="code_line">&nbsp;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;var s := LoadFile(TPath.Combine(TPath.GetDocumentsPath, &#39;latin-lipsum.txt&#39;));</div><div class="code_line">&nbsp;&nbsp;var words := TCollections.CreateList&#60;string&#62;(s.Split([&#39; &#39;])); &nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;var sw:= TStopwatch.StartNew;</div><div class="code_line">&nbsp;&nbsp;var distinctWords:= TEnumerable.Distinct&#60;string&#62;(words);</div><div class="code_line">&nbsp;&nbsp;var arrayWords:= distinctWords.ToArray;</div><div class="code_line">&nbsp;&nbsp;sw.Stop;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;Writeln(Format(&#39;Distinct Words: %d, %d ms&#39;, [distinctWords.Count, sw.ElapsedMilliseconds]));</div><div class="code_line">// Distinct Words: 781, 1 ms</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;var distinctWords2 := TCollections.CreateList&#60;string&#62;;</div><div class="code_line">&nbsp;&nbsp;sw.Reset;</div><div class="code_line">&nbsp;&nbsp;sw.Start;</div><div class="code_line">&nbsp;&nbsp;for var word in words do</div><div class="code_line">&nbsp;&nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp;if distinctWords2.IndexOf(word) = -1 then</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;distinctWords2.Add(word);</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;&nbsp;sw.Stop;</div><div class="code_line">&nbsp;&nbsp;Writeln(Format(&#39;Distinct2 Words: %d, %d ms&#39;, [distinctWords2.Count, sw.ElapsedMilliseconds]));</div><div class="code_line">// Distinct Words: 781, 12 ms</div><div class="code_line">end;</div></ol></div></div></div></div>]]></description>
        <author>Cfon</author>
        <category>Delphi: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3795571</guid>
        <pubDate>Sun, 14 Apr 2019 07:11:38 +0000</pubDate>
        <title>Spring4D</title>
        <link>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3795571</link>
        <description><![CDATA[Cfon: Рефакторим CreateRecipes в примере из поста #16:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">...</div><div class="code_line">&nbsp;&nbsp;type TMapFunc&#60;T&#62; = reference to function (Value: TJSONValue): T;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;TRecipesManager = record</div><div class="code_line">&nbsp;&nbsp; &nbsp;class function LoadFile(fileName: string): string; static;</div><div class="code_line">&nbsp;&nbsp; &nbsp;class function CreateRecipes(json: string): IList&#60;TRecipe&#62;; static;</div><div class="code_line">&nbsp;&nbsp; &nbsp;class function CreateIngredients(AValues: TJSONArray): IList&#60;TIngredient&#62;; static;</div><div class="code_line">&nbsp;&nbsp; &nbsp;class function CreateSteps(AValues: TJSONArray): IList&#60;string&#62;; static;</div><div class="code_line">&nbsp;&nbsp; &nbsp;class function Map&#60;T&#62;(const AValues: TJSONArray; AFunc: TMapFunc&#60;T&#62;): IList&#60;T&#62;; static;</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;TJSONParser = record</div><div class="code_line">&nbsp;&nbsp; &nbsp;class function GetRoot(json: string): TJSONValue; static;</div><div class="code_line">&nbsp;&nbsp; &nbsp;class function GetNumber(AValue: TJSONValue; APath: string): integer; static;</div><div class="code_line">&nbsp;&nbsp; &nbsp;class function GetDouble(AValue: TJSONValue; APath: string): Double; static;</div><div class="code_line">&nbsp;&nbsp; &nbsp;class function GetString(AValue: TJSONValue; APath: string): string; static;</div><div class="code_line">&nbsp;&nbsp; &nbsp;class function GetArray(AValue: TJSONValue; APath: string): TJSONArray; static;</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;</div><div class="code_line">....</div><div class="code_line">&nbsp;</div><div class="code_line">{ TJSONParser }</div><div class="code_line">&nbsp;</div><div class="code_line">class function TJSONParser.GetArray(AValue: TJSONValue;</div><div class="code_line">&nbsp;&nbsp;APath: string): TJSONArray;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;Result:= AValue.GetValue&#60;TJSONArray&#62;(APath);</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">class function TJSONParser.GetDouble(AValue: TJSONValue; APath: string): Double;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;Result:= AValue.GetValue&#60;Double&#62;(APath);</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">class function TJSONParser.GetNumber(AValue: TJSONValue;</div><div class="code_line">&nbsp;&nbsp;APath: string): integer;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;Result:= AValue.GetValue&#60;integer&#62;(APath);</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">class function TJSONParser.GetRoot(json: string): TJSONValue;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;Result:= TJSONObject.ParseJSONValue(json);</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">class function TJSONParser.GetString(AValue: TJSONValue; APath: string): string;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;Result:= AValue.GetValue&#60;string&#62;(APath);</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">{ TRecipesManager }</div><div class="code_line">&nbsp;</div><div class="code_line">class function TRecipesManager.Map&#60;T&#62;(const AValues: TJSONArray;</div><div class="code_line">&nbsp;&nbsp;AFunc: TMapFunc&#60;T&#62;): IList&#60;T&#62;;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;Result:= TCollections.CreateList&#60;T&#62;;</div><div class="code_line">&nbsp;&nbsp;for var val in AValues do</div><div class="code_line">&nbsp;&nbsp; &nbsp;Result.Add(AFunc(val));</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">class function TRecipesManager.CreateIngredients(</div><div class="code_line">&nbsp;&nbsp;AValues: TJSONArray): IList&#60;TIngredient&#62;;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;Result:= TRecipesManager.Map&#60;TIngredient&#62;(AValues,</div><div class="code_line">&nbsp;&nbsp; &nbsp;function (ingr: TJSONValue): TIngredient</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Result:= TIngredient.Create(</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;TJSONParser.GetString(ingr, &#39;name&#39;),</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;TJSONParser.GetDouble(ingr, &#39;amount&#39;),</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;TJSONParser.GetString(ingr, &#39;measurement&#39;));</div><div class="code_line">&nbsp;&nbsp; &nbsp;end);</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">class function TRecipesManager.CreateRecipes(json: string): IList&#60;TRecipe&#62;;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;Result:= TCollections.CreateList&#60;TRecipe&#62;;</div><div class="code_line">&nbsp;&nbsp;try</div><div class="code_line">&nbsp;&nbsp; &nbsp;var Root:= TJSONParser.GetRoot(json);</div><div class="code_line">&nbsp;&nbsp; &nbsp;var Recipes := TJSONParser.GetArray(Root, &#39;recipes&#39;);</div><div class="code_line">&nbsp;&nbsp; &nbsp;try</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Result:= TRecipesManager.Map&#60;TRecipe&#62;(Recipes,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;function (recipe: TJSONValue): TRecipe</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;var id:= TJSONParser.GetNumber(recipe, &#39;id&#39;);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;var name:= TJSONParser.GetString(recipe, &#39;name&#39;);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;var rating:= &nbsp;TJSONParser.GetNumber(recipe, &#39;rating&#39;);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;var ingredients:= CreateIngredients(</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;TJSONParser.GetArray(recipe, &#39;ingredients&#39;));</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;var steps:= CreateSteps(TJSONParser.GetArray(recipe, &#39;steps&#39;));</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Result:= TRecipe.Create(id, name, ingredients, steps, rating);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;end);</div><div class="code_line">&nbsp;&nbsp; &nbsp;finally</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Recipes.Free;</div><div class="code_line">&nbsp;&nbsp; &nbsp;end;</div><div class="code_line">&nbsp;&nbsp;except</div><div class="code_line">&nbsp;&nbsp; &nbsp;on EJSONException do</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Writeln(&#39;Error parsing JSON. Check file format.&#39;);</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">class function TRecipesManager.CreateSteps(AValues: TJSONArray): IList&#60;string&#62;;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;Result:= TRecipesManager.Map&#60;string&#62;(AValues,</div><div class="code_line">&nbsp;&nbsp; &nbsp;function (step: TJSONValue): string</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Result:= step.Value;</div><div class="code_line">&nbsp;&nbsp; &nbsp;end);</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">class function TRecipesManager.LoadFile(fileName: string): string;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;var reader:= TStreamReader.Create(fileName);</div><div class="code_line">&nbsp;&nbsp;try</div><div class="code_line">&nbsp;&nbsp; &nbsp;Result:= reader.ReadToEnd;</div><div class="code_line">&nbsp;&nbsp;finally</div><div class="code_line">&nbsp;&nbsp; &nbsp;reader.Free;</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;// load json file.</div><div class="code_line">&nbsp;&nbsp;var s:= TRecipesManager.LoadFile(TPath.Combine(</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;TPath.GetDocumentsPath, &#39;recipes.json&#39;));</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// create recipes list.</div><div class="code_line">&nbsp;&nbsp;var recipes: IList&#60;TRecipe&#62; := TRecipesManager.CreateRecipes(s);</div><div class="code_line">&nbsp;</div><div class="code_line">....</div><div class="code_line">&nbsp;</div><div class="code_line">end.</div></ol></div></div></div></div><br>
- А зачем в CreateRecipes лишний начальный Result:= TCollections.CreateList&lt;TRecipe&gt; получается дважды выделяется память&#33;  :huh: <br>
Это мой стиль программирования&#33; Я не лублу проверять результат операции типо <br>
if not Assigned(recipes) then Exit на случай ошибки :D<br>
- Надо думаю лучше все же вставить проверку  :huh: <br>
Ага себе вставь ее  :lool: <br>
Моя стиль прогить с позиции изначально нет ошибок&#33; Я это называю &quot;<strong class='tag-b'>оптимистиское программирование</strong>&quot;&#33; О надо бы зарегить термин за авторством :D <br>
- Спасибо маста вы гений&#33;  :scratch:  <br>
А то  :D]]></description>
        <author>Cfon</author>
        <category>Delphi: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3795568</guid>
        <pubDate>Sun, 14 Apr 2019 06:11:13 +0000</pubDate>
        <title>Spring4D</title>
        <link>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3795568</link>
        <description><![CDATA[Cfon: Еще одно замечание  по поводу след.кода<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">.....</div><div class="code_line">&nbsp;&nbsp;// Determine which people have pets that are all older than 5.</div><div class="code_line">&nbsp;&nbsp;var Persons := People.Where(function (const person: TPerson): Boolean</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Result:= person.Pets.All(function (const pet: TPet): boolean</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Result:= pet.Age &#62; 5;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;end);</div><div class="code_line">&nbsp;&nbsp; &nbsp;end);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;var Names := TEnumerable.Select&#60;TPerson, string&#62;(Persons,</div><div class="code_line">&nbsp;&nbsp; &nbsp;function (person: TPerson): string</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Result:= person.LastName;</div><div class="code_line">&nbsp;&nbsp; &nbsp;end);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;Names.ForEach(procedure (const name: string)</div><div class="code_line">&nbsp;&nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp;Writeln(name);</div><div class="code_line">&nbsp;&nbsp;end);</div><div class="code_line">end.</div></ol></div></div></div></div><br>
Тут на самом деле выполнятся только один цикл&#33; Так что нет никаких многоразовых проходов по одному и тому же списку. <br>
Where и Select задают операции которые надо произвести, а сам цикл по списку уже выполнит ForEach&#33; Крутяк да? :D <br>
- А как быть если результат нужена сохранить без ForEach?  :huh: <br>
Кол метод ToArray :D]]></description>
        <author>Cfon</author>
        <category>Delphi: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3795533</guid>
        <pubDate>Sat, 13 Apr 2019 12:55:33 +0000</pubDate>
        <title>Spring4D</title>
        <link>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3795533</link>
        <description><![CDATA[Cfon: Теперь мой пример с рецептами, юзаем IEnumerable&lt;T&gt;.<strong class='tag-b'>Any</strong>, дополнительно юзанул анонимку, ну так для примера  :D <br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">procedure ProcessRecipes;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;// load json file.</div><div class="code_line">&nbsp;&nbsp;var s:= LoadFile(&#39;recipes.json&#39;);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// create recipes list.</div><div class="code_line">&nbsp;&nbsp;var recipes := CreateRecipes(s);</div><div class="code_line">...</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;var recipeByIngr:= function (ingredientName: string): IEnumerable&#60;TRecipe&#62;</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Result:= recipes.Where(function (const recipe: TRecipe): Boolean</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Result:= recipe.Ingredients.Any(function (const ingr: TIngredient): Boolean</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Result:= ingr.IngredientName.ToLower.Contains(ingredientName.ToLower);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;end);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;end);</div><div class="code_line">&nbsp;&nbsp; &nbsp;end;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// получаем список рецептов, где название </div><div class="code_line">&nbsp;&nbsp;// ингредиента содержит слово &#39;lettuce&#39;</div><div class="code_line">&nbsp;&nbsp;var query3:= recipeByIngr(&#39;lettuce&#39;);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// print the results.</div><div class="code_line">&nbsp;&nbsp;query3.ForEach(procedure (const recipe: TRecipe)</div><div class="code_line">&nbsp;&nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp;Writeln(recipe.RecipeName);</div><div class="code_line">&nbsp;&nbsp;end);</div><div class="code_line">&nbsp;&nbsp;// Baked Salmon</div><div class="code_line">&nbsp;&nbsp;// Fish Tacos</div><div class="code_line">end;</div></ol></div></div></div></div><br>
Название ингредиента передается как параметр, а recipes через замыкание.]]></description>
        <author>Cfon</author>
        <category>Delphi: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3795524</guid>
        <pubDate>Sat, 13 Apr 2019 08:09:21 +0000</pubDate>
        <title>Spring4D</title>
        <link>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3795524</link>
        <description><![CDATA[Cfon: <div class='tag-quote'><a class='tag-quote-link' href='https://forum.sources.ru/index.php?showtopic=414484&view=findpost&p=3795492'><span class='tag-quote-prefix'>Цитата</span></a> <span class='tag-quote__quote-info'>Cfon &#064; <time class="tag-quote__quoted-time" datetime="2019-04-12T18:13:49+00:00">12.04.19, 18:13</time></span><div class='quote '>Т.е реальный запрос будет выполнен только тогда когда будет первое обращение нет даже не к Persons, а к Names&#33; :hang:</div></div><br>
На самом деле при обращении к Persons тоже запрос выполниться, просто в селекте нет обращения к Persons, поэтому наш запрос будет выполнен тока в строке Names.ForEach, это я и имел ввиду.<br>
<br>
- А что делать если нам надо, чтобы значение age было то что определено перед фильтрацией?  :huh: <br>
Решение простое надо зафиксировать значение age  :D <br>
- Как?&#33; :blink: <br>
Например вот так  :D<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;&nbsp;var age:= 5;</div><div class="code_line">&nbsp;&nbsp;// Determine which people have pets that are all older than 5.</div><div class="code_line">&nbsp;&nbsp;var Persons := (function (age: integer): IEnumerable&#60;TPerson&#62;</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Result:= People.Where(function (const person: TPerson): Boolean</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Result:= person.Pets.All(function (const pet: TPet): boolean</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Result:= pet.Age &#62; age;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;end);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;end);</div><div class="code_line">&nbsp;&nbsp; &nbsp;end)(age);</div><div class="code_line">&nbsp;&nbsp;age:= 10; //это уже не влияет на предыдущий результат</div></ol></div></div></div></div><br>
Ну или определить отдельно функцию и передавать туда age, в принципе тоже что и щас  :D<br>
<br>
А можно еще такую тему зафигачить  :D <br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">var PersonFilter := function (APersons: IEnumerable&#60;TPerson&#62;):</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;TFunc&#60;integer, IEnumerable&#60;TPerson&#62;&#62;</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Result:= function (age: integer): IEnumerable&#60;TPerson&#62;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Result := APersons.Where(function (const person: TPerson): Boolean</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Result:= person.Pets.All(function (const pet: TPet): boolean</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Result:= pet.Age &#62; age;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;end);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;end);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;end;</div><div class="code_line">&nbsp;&nbsp; &nbsp;end;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;var FilterByPeople:= PersonFilter(People);</div><div class="code_line">&nbsp;&nbsp;var Persons:= FilterByPeople(age);</div></ol></div></div></div></div><br>
Ну тут я заюзал частичное применение для фиксации первого параметра, в данном случае ссылки на список People.<br>
- Зачем нам его фиксировать?  :huh: <br>
Ну это удобно когда нам надо часто вызывать одну и туже фильтрацию для разных значений age  :D<br>
В данном случае в принципе можно и два передать не страшно, а если к примеру у нас есть функция где много параметров? Причем все кроме одного остальные не меняются, вот тогда можно заюзать частичное применение и создать функцию с меньшим числом параметром.]]></description>
        <author>Cfon</author>
        <category>Delphi: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3795492</guid>
        <pubDate>Fri, 12 Apr 2019 18:13:49 +0000</pubDate>
        <title>Spring4D</title>
        <link>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3795492</link>
        <description><![CDATA[Cfon: Обнаружил случайно один интресный момент в работе коллекций Spring4D, суть вот в чем, давайте расмотрим внимательно кусок пред кода<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">.....</div><div class="code_line">&nbsp;&nbsp;// Determine which people have pets that are all older than 5.</div><div class="code_line">&nbsp;&nbsp;var Persons := People.Where(function (const person: TPerson): Boolean</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Result:= person.Pets.All(function (const pet: TPet): boolean</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Result:= pet.Age &#62; 5;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;end);</div><div class="code_line">&nbsp;&nbsp; &nbsp;end);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;var Names := TEnumerable.Select&#60;TPerson, string&#62;(Persons,</div><div class="code_line">&nbsp;&nbsp; &nbsp;function (person: TPerson): string</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Result:= person.LastName;</div><div class="code_line">&nbsp;&nbsp; &nbsp;end</div><div class="code_line">&nbsp;&nbsp;);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;Names.ForEach(procedure (const name: string)</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Writeln(name);</div><div class="code_line">&nbsp;&nbsp; &nbsp;end</div><div class="code_line">&nbsp;&nbsp;);</div><div class="code_line">end.</div></ol></div></div></div></div><br>
тут в анонимке Where явно задан значение 5, как правило в рилкоде там будет переменная, давайте изменим это участок кода<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">.....</div><div class="code_line">&nbsp;&nbsp;var age:= 5;</div><div class="code_line">&nbsp;&nbsp;// Determine which people have pets that are all older than 5.</div><div class="code_line">&nbsp;&nbsp;var Persons := People.Where(function (const person: TPerson): Boolean</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Result:= person.Pets.All(function (const pet: TPet): boolean</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Result:= pet.Age &#62; age;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;end);</div><div class="code_line">&nbsp;&nbsp; &nbsp;end);</div><div class="code_line">.....</div></ol></div></div></div></div><br>
ОК, тут вроде все понятно age замкнулась (захвачена) в анонимке All. Все супер, а теперь давайте изменим значение age где-нибудь ниже по коду:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">.....</div><div class="code_line">&nbsp;&nbsp;var age:= 5;</div><div class="code_line">&nbsp;&nbsp;// Determine which people have pets that are all older than 5.</div><div class="code_line">&nbsp;&nbsp;var Persons := People.Where(function (const person: TPerson): Boolean</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Result:= person.Pets.All(function (const pet: TPet): boolean</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Result:= pet.Age &#62; age;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;end);</div><div class="code_line">&nbsp;&nbsp; &nbsp;end);</div><div class="code_line">&nbsp;&nbsp;</div><div class="code_line">&nbsp;&nbsp;age:=10;</div><div class="code_line">.....</div></ol></div></div></div></div><br>
и как вы думаете каков будет результат запроса? <br>
Name.ForEach выведет список имен персон, у которых возраст петс нет не &gt; 5, a age &gt; 10&#33;  :D<br>
Что происходит?  :o <br>
А происходит так называемое отложенное вычисление&#33;  <br>
Круто да?  :D<br>
Т.е реальный запрос будет выполнен только тогда когда будет первое обращение нет даже не к Persons, а к Names&#33; :hang:]]></description>
        <author>Cfon</author>
        <category>Delphi: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3795478</guid>
        <pubDate>Fri, 12 Apr 2019 12:01:29 +0000</pubDate>
        <title>Spring4D</title>
        <link>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3795478</link>
        <description><![CDATA[Cfon: А вот пример с IEnumerable&lt;T&gt;.<strong class='tag-b'>All</strong> поинтереснее, тут All заюзан с Where и завершен Select&#39;ом. Сам пример на C# приводится в Linq синтаксисе, так что не сразу понятно как это будет на Делфях:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;var People:= TCollections.CreateList&#60;TPerson&#62;([</div><div class="code_line">&nbsp;&nbsp; &nbsp;TPerson.Create(&#39;Haas&#39;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;TCollections.CreateList&#60;TPet&#62;([TPet.Create(&#39;Barley&#39;, 10),</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; TPet.Create(&#39;Boots&#39;, 14),</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; TPet.Create(&#39;Whiskley&#39;, 6)])),</div><div class="code_line">&nbsp;&nbsp; &nbsp;TPerson.Create(&#39;Fakhouri&#39;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;TCollections.CreateList&#60;TPet&#62;([TPet.Create(&#39;Snowball&#39;, 1)])),</div><div class="code_line">&nbsp;&nbsp; &nbsp;TPerson.Create(&#39;Antebi&#39;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;TCollections.CreateList&#60;TPet&#62;([TPet.Create(&#39;Belle&#39;, 8)])),</div><div class="code_line">&nbsp;&nbsp; &nbsp;TPerson.Create(&#39;Philips&#39;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;TCollections.CreateList&#60;TPet&#62;([TPet.Create(&#39;Sweetie&#39;, 2),</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; TPet.Create(&#39;Rover&#39;, 13)]))</div><div class="code_line">&nbsp;&nbsp;]);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// Determine which people have pets that are all older than 5.</div><div class="code_line">&nbsp;&nbsp;var Persons := People.Where(function (const person: TPerson): Boolean</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Result:= person.Pets.All(function (const pet: TPet): boolean</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Result:= pet.Age &#62; 5;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;end);</div><div class="code_line">&nbsp;&nbsp; &nbsp;end);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;var Names := TEnumerable.Select&#60;TPerson, string&#62;(Persons,</div><div class="code_line">&nbsp;&nbsp; &nbsp;function (person: TPerson): string</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Result:= person.LastName;</div><div class="code_line">&nbsp;&nbsp; &nbsp;end</div><div class="code_line">&nbsp;&nbsp;);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;Names.ForEach(procedure (const name: string)</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Writeln(name);</div><div class="code_line">&nbsp;&nbsp; &nbsp;end</div><div class="code_line">&nbsp;&nbsp;);</div><div class="code_line">end.</div><div class="code_line">(*List&#60;Person&#62; people = new List&#60;Person&#62;</div><div class="code_line">&nbsp;&nbsp; &nbsp;{ new Person { LastName = &quot;Haas&quot;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Pets = new Pet[] { new Pet { Name=&quot;Barley&quot;, Age=10 },</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;new Pet { Name=&quot;Boots&quot;, Age=14 },</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;new Pet { Name=&quot;Whiskers&quot;, Age=6 }}},</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;new Person { LastName = &quot;Fakhouri&quot;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Pets = new Pet[] { new Pet { Name = &quot;Snowball&quot;, Age = 1}}},</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;new Person { LastName = &quot;Antebi&quot;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Pets = new Pet[] { new Pet { Name = &quot;Belle&quot;, Age = 8} }},</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;new Person { LastName = &quot;Philips&quot;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Pets = new Pet[] { new Pet { Name = &quot;Sweetie&quot;, Age = 2},</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;new Pet { Name = &quot;Rover&quot;, Age = 13}} }</div><div class="code_line">&nbsp;&nbsp; &nbsp;};</div><div class="code_line">&nbsp;</div><div class="code_line">// Determine which people have pets that are all older than 5.</div><div class="code_line">IEnumerable&#60;string&#62; names = from person in people</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;where person.Pets.All(pet =&#62; pet.Age &#62; 5)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;select person.LastName;</div><div class="code_line">&nbsp;</div><div class="code_line">foreach (string name in names)</div><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp; &nbsp;Console.WriteLine(name);</div><div class="code_line">}</div><div class="code_line">&nbsp;</div><div class="code_line">/* This code produces the following output:</div><div class="code_line">&nbsp;*</div><div class="code_line">&nbsp;* Haas</div><div class="code_line">&nbsp;* Antebi</div><div class="code_line">&nbsp;*/*)</div></ol></div></div></div></div><br>
Я ща буду в основном юзать списки (IList&lt;T&gt;) вместо массивов (Enumerable&lt;T&gt;), по причине непонятных тупяков Делфи :D <br>
Каких? У меня на Enumerable часто вылетают каки :D <br>
Не буду их описывать, возможно кто юзал тот в курсе  :crazy:<br>
<br>
Да и не путайте IEnumerable&lt;T&gt; c Enumerable&lt;T&gt;. <br>
IEnumerable&lt;T&gt; это интерфес, который реализуют различные структуры данных такие как TList&lt;T&gt;, а Enumerable&lt;T&gt; это запись, которая агрегирует этот интерфейс, и реализует его как итератор массива, ну и реализует большой набор методов для работы над этим массивом.<br>
<br>
Вот что еще интересно, обратите внимание на то что в предикат передается константный параметр (см. All, Where), а вот в анонимке Select&#39;а передается неконстантный параметр, это позволит изменить сам список, если в качестве значения передается объект класса, а не запись, например допустим что TPerson = class, тогда<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">var Names := TEnumerable.Select&#60;TPerson, string&#62;(Persons,</div><div class="code_line">&nbsp;&nbsp; &nbsp;function (person: TPerson): string</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;person.LastName := person.LastName.ToUpper; //&#60;-- меняем значение LastName </div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Result:= person.LastName;</div><div class="code_line">&nbsp;&nbsp; &nbsp;end</div><div class="code_line">&nbsp;&nbsp;);</div></ol></div></div></div></div><br>
в итоге имеем измененый список People и Persons, почему в селектах так я беспонятий :D]]></description>
        <author>Cfon</author>
        <category>Delphi: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3795433</guid>
        <pubDate>Fri, 12 Apr 2019 06:55:35 +0000</pubDate>
        <title>Spring4D</title>
        <link>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3795433</link>
        <description><![CDATA[Cfon: <div class='tag-quote'><a class='tag-quote-link' href='https://forum.sources.ru/index.php?showtopic=414484&view=findpost&p=3795370'><span class='tag-quote-prefix'>Цитата</span></a> <span class='tag-quote__quote-info'>Cfon &#064; <time class="tag-quote__quoted-time" datetime="2019-04-11T11:59:23+00:00">11.04.19, 11:59</time></span><div class='quote '>Как же обобщить для двух разных типов  :wacko:</div></div><br>
Все понел, в Spring.Collections.Enumerable нет метода Aggregate с соотвест. сигнатурой там тока для TFunc&lt;T,T&gt;. <br>
Да и в моем случае TFunc&lt;T,R&gt; тоже не катит, тут надо не через обобщения, а нужна динамическая типизация как в JS. <br>
Так что пока варик TFunc&lt;T,T&gt; покатит.<br>
<br>
Ну а пока продолжаю выкладывать другую муру  :D <br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">uses</div><div class="code_line">&nbsp;&nbsp;System.SysUtils,</div><div class="code_line">&nbsp;&nbsp;Spring.Collections;</div><div class="code_line">&nbsp;</div><div class="code_line">type</div><div class="code_line">&nbsp;&nbsp;TPet = record</div><div class="code_line">&nbsp;&nbsp; &nbsp;Name: string;</div><div class="code_line">&nbsp;&nbsp; &nbsp;Age: integer;</div><div class="code_line">&nbsp;&nbsp; &nbsp;constructor Create(AName: string; AAge:integer);</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;</div><div class="code_line">{ TPet }</div><div class="code_line">&nbsp;</div><div class="code_line">constructor TPet.Create(AName: string; AAge: integer);</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;Name:= AName;</div><div class="code_line">&nbsp;&nbsp;Age:= AAge;</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;// Create an array of Pets.</div><div class="code_line">&nbsp;&nbsp;var pets:= TCollections.CreateList&#60;TPet&#62;([</div><div class="code_line">&nbsp;&nbsp; &nbsp;TPet.Create(&#39;Barley&#39;, 10),</div><div class="code_line">&nbsp;&nbsp; &nbsp;TPet.Create(&#39;Boots&#39;, 4),</div><div class="code_line">&nbsp;&nbsp; &nbsp;TPet.Create(&#39;Whiskers&#39;, 6)</div><div class="code_line">&nbsp;&nbsp;]);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// Determine whether all pet names</div><div class="code_line">&nbsp;&nbsp;// in the array start with &#39;B&#39;.</div><div class="code_line">&nbsp;&nbsp;var allStartWithB:= pets.All(function (const pet: TPet): boolean</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Result:= pet.Name.StartsWith(&#39;B&#39;);</div><div class="code_line">&nbsp;&nbsp; &nbsp;end);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;if allStartWithB then</div><div class="code_line">&nbsp;&nbsp; &nbsp;WriteLn(&#39;All pet names start with &quot;B&quot;.&#39;)</div><div class="code_line">&nbsp;&nbsp;else</div><div class="code_line">&nbsp;&nbsp; &nbsp;WriteLn(&#39;Not all pet names start with &quot;B&quot;.&#39;);</div><div class="code_line">end;</div><div class="code_line">(* C# code:</div><div class="code_line">// Create an array of Pets.</div><div class="code_line">&nbsp;&nbsp; &nbsp;Pet[] pets = { new Pet { Name=&quot;Barley&quot;, Age=10 },</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; new Pet { Name=&quot;Boots&quot;, Age=4 },</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; new Pet { Name=&quot;Whiskers&quot;, Age=6 } };</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;// Determine whether all pet names</div><div class="code_line">&nbsp;&nbsp; &nbsp;// in the array start with &#39;B&#39;.</div><div class="code_line">&nbsp;&nbsp; &nbsp;bool allStartWithB = pets.All(pet =&#62;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pet.Name.StartsWith(&quot;B&quot;));</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;Console.WriteLine(</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;&quot;{0} pet names start with &#39;B&#39;.&quot;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;allStartWithB ? &quot;All&quot; : &quot;Not all&quot;);</div><div class="code_line">&nbsp;</div><div class="code_line">// This code produces the following output:</div><div class="code_line">//</div><div class="code_line">// &nbsp;Not all pet names start with &#39;B&#39;.*)</div><div class="code_line">end.</div></ol></div></div></div></div> <br>
<br>
<span class="tag-color tag-color-named" data-value="mergepost" style="color: mergepost"><span class='tag-size' data-value='7' style='font-size:7pt;'>Добавлено <time class="tag-mergetime" datetime="2019-04-12T07:02:12+00:00">12.04.19, 07:02</time></span></span><br>
<div class='tag-quote'><a class='tag-quote-link' href='https://forum.sources.ru/index.php?showtopic=414484&view=findpost&p=3795432'><span class='tag-quote-prefix'>Цитата</span></a> <span class='tag-quote__quote-info'>jack128 &#064; <time class="tag-quote__quoted-time" datetime="2019-04-12T06:52:43+00:00">12.04.19, 06:52</time></span><div class='quote '><div class='tag-quote'><a class='tag-quote-link' href='https://forum.sources.ru/index.php?showtopic=414484&view=findpost&p=3795370'><span class='tag-quote-prefix'>Цитата</span></a> <span class='tag-quote__quote-info'>Cfon &#064; <time class="tag-quote__quoted-time" datetime="2019-04-11T11:59:23+00:00">11.04.19, 11:59</time></span><div class='quote '>Как же обобщить для двух разных типов</div></div><br>
конкретно в дельфи - никак. Возможно в плюсах можно (гугли variadic templates) или в соседнем подформуе спрашивай</div></div><br>
ОК.]]></description>
        <author>Cfon</author>
        <category>Delphi: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3795432</guid>
        <pubDate>Fri, 12 Apr 2019 06:52:43 +0000</pubDate>
        <title>Spring4D</title>
        <link>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3795432</link>
        <description><![CDATA[jack128: <div class='tag-quote'><a class='tag-quote-link' href='https://forum.sources.ru/index.php?showtopic=414484&view=findpost&p=3795370'><span class='tag-quote-prefix'>Цитата</span></a> <span class='tag-quote__quote-info'>Cfon &#064; <time class="tag-quote__quoted-time" datetime="2019-04-11T11:59:23+00:00">11.04.19, 11:59</time></span><div class='quote '>Как же обобщить для двух разных типов</div></div><br>
конкретно в дельфи - никак. Возможно в плюсах можно (гугли variadic templates) или в соседнем подформуе спрашивай]]></description>
        <author>jack128</author>
        <category>Delphi: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3795370</guid>
        <pubDate>Thu, 11 Apr 2019 11:59:23 +0000</pubDate>
        <title>Spring4D</title>
        <link>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3795370</link>
        <description><![CDATA[Cfon: Задание оказалось очень сложным  :wall: <br>
Вот что я осилил, комплятор ругается ошибка типов, я даже не буду приводить ее тут ибо один фиг не понятная  :D <br>
Все я пас, сами мучайтесь :D <br>
Кто решит я буду плюсовать пока я жив  :lool:  <br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">type</div><div class="code_line">&nbsp;&nbsp;TFunctionalUtils = record</div><div class="code_line">&nbsp;&nbsp; &nbsp;class function Compose&#60;T,R&#62;(fns: Enumerable&#60;TFunc&#60;T,R&#62;&#62;): TFunc&#60;T, R&#62;; static;</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;</div><div class="code_line">{ TFunctionalUtils }</div><div class="code_line">&nbsp;</div><div class="code_line">class function TFunctionalUtils.Compose&#60;T, R&#62;(</div><div class="code_line">&nbsp;&nbsp;fns: Enumerable&#60;TFunc&#60;T, R&#62;&#62;): TFunc&#60;T, R&#62;;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;Result:= function (arg: T): R</div><div class="code_line">&nbsp;&nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp;Result:= fns.Aggregate&#60;T&#62;(arg,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;function (composed: T; f: TFunc&#60;T, R&#62;): R</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Result:= f(composed);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;end);</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">end;</div></ol></div></div></div></div> <br>
<br>
<span class="tag-color tag-color-named" data-value="mergepost" style="color: mergepost"><span class='tag-size' data-value='7' style='font-size:7pt;'>Добавлено <time class="tag-mergetime" datetime="2019-04-11T12:42:45+00:00">11.04.19, 12:42</time></span></span><br>
Не я пока тут малеха перекурил и меня осенило чекануть на конкрит дата :D <br>
Проверил для целых чисел и что вы думаете работает&#33; Как же все это дело обобщить :wacko:  <br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">class function TFunctionalUtils.Compose(</div><div class="code_line">&nbsp;&nbsp;fns: Enumerable&#60;TFunc&#60;integer, integer&#62;&#62;): TFunc&#60;integer, integer&#62;;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;Result:= function (arg: integer): integer</div><div class="code_line">&nbsp;&nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp;Result:= fns.Aggregate&#60;integer&#62;(arg,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;function (composed: integer; f: TFunc&#60;integer, integer&#62;): integer</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Result:= f(composed);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;end);</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">function Add5(i: integer): integer;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;Result:= i + 5;</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">function Add7(i: integer): integer;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;Result:= i + 7;</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;i: integer;</div><div class="code_line">&nbsp;&nbsp;funcs: Enumerable&#60;TFunc&#60;integer,integer&#62;&#62;;</div><div class="code_line">&nbsp;&nbsp;func: TFunc&#60;integer,integer&#62;;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;funcs:= Enumerable&#60;TFunc&#60;integer,integer&#62;&#62;.Create([Add5, Add7]);</div><div class="code_line">&nbsp;&nbsp;func:= &nbsp;TFunctionalUtils.Compose(funcs);</div><div class="code_line">&nbsp;&nbsp;i:= func(10);</div><div class="code_line">&nbsp;&nbsp;Writeln(i);</div><div class="code_line">// Output: 22</div><div class="code_line">end.</div></ol></div></div></div></div> <br>
<br>
<span class="tag-color tag-color-named" data-value="mergepost" style="color: mergepost"><span class='tag-size' data-value='7' style='font-size:7pt;'>Добавлено <time class="tag-mergetime" datetime="2019-04-11T12:56:18+00:00">11.04.19, 12:56</time></span></span><br>
О обобщил для одного типа  :D <br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">class function TFunctionalUtils.Compose&#60;T&#62;(</div><div class="code_line">&nbsp;&nbsp;fns: Enumerable&#60;TFunc&#60;T, T&#62;&#62;): TFunc&#60;T, T&#62;;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;Result:= function (arg: T): T</div><div class="code_line">&nbsp;&nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp;Result:= fns.Aggregate&#60;T&#62;(arg,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;function (composed: T; f: TFunc&#60;T, T&#62;): T</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Result:= f(composed);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;end);</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">end;</div></ol></div></div></div></div><br>
Как же обобщить для двух разных типов  :wacko:]]></description>
        <author>Cfon</author>
        <category>Delphi: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3795362</guid>
        <pubDate>Thu, 11 Apr 2019 10:48:52 +0000</pubDate>
        <title>Spring4D</title>
        <link>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3795362</link>
        <description><![CDATA[Cfon: Задание&#33; :D <br>
Надо перевести код JS на делфи:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">const compose = (...fns) =&#62;</div><div class="code_line">&nbsp;(arg) =&#62;</div><div class="code_line">&nbsp;fns.reduce(</div><div class="code_line">&nbsp;(composed, f) =&#62; f(composed),</div><div class="code_line">&nbsp;arg</div><div class="code_line">&nbsp;)</div></ol></div></div></div></div><br>
- Что это за мура? :lool: <br>
Это не мура&#33; Это функция высшего порядка композиция&#33;  :D<br>
- Что она делает?  :blink: <br>
Композиция получает список функций, выполняет последовательно над агрументом действия и возвращает результат.]]></description>
        <author>Cfon</author>
        <category>Delphi: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3795281</guid>
        <pubDate>Wed, 10 Apr 2019 12:06:26 +0000</pubDate>
        <title>Spring4D</title>
        <link>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3795281</link>
        <description><![CDATA[Fr0sT: <div class='tag-quote'><a class='tag-quote-link' href='https://forum.sources.ru/index.php?showtopic=414484&view=findpost&p=3795150'><span class='tag-quote-prefix'>Цитата</span></a> <span class='tag-quote__quote-info'>Cfon &#064; <time class="tag-quote__quoted-time" datetime="2019-04-09T12:08:05+00:00">09.04.19, 12:08</time></span><div class='quote '><div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">const colors = [&quot;red&quot;, &quot;red&quot;, &quot;green&quot;, &quot;blue&quot;, &quot;green&quot;];</div><div class="code_line">const distinctColors = colors.reduce(</div><div class="code_line">&nbsp;&nbsp;(distinct, color) =&#62; </div><div class="code_line">&nbsp;&nbsp; &nbsp;(distinct.indexOf(color) !== -1) ? </div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;distinct : </div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;[...distinct, color],</div><div class="code_line">[]);</div><div class="code_line">&nbsp;</div><div class="code_line">console.log(distinctColors);</div><div class="code_line">// [&quot;red&quot;, &quot;green&quot;, &quot;blue&quot;]</div></ol></div></div></div></div></div></div><br>
Не все йогурты одинаково полезны.<br>
На мой консервативный взгляд, этот код - отличное доказательство того, как простые операции превращаются в малопонятную хрень из тысяч анонимок, методов, перераспределений и тому подобной муры.<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">const colors = [&quot;red&quot;, &quot;red&quot;, &quot;green&quot;, &quot;blue&quot;, &quot;green&quot;];</div><div class="code_line">const distinctColors = [];</div><div class="code_line">for (let col of colors)</div><div class="code_line">&nbsp;&nbsp;if (distinctColors.indexOf(col) == -1)</div><div class="code_line">&nbsp;&nbsp; &nbsp;distinctColors.push(col);</div></ol></div></div></div></div> <br>
<br>
<span class="tag-color tag-color-named" data-value="mergepost" style="color: mergepost"><span class='tag-size' data-value='7' style='font-size:7pt;'>Добавлено <time class="tag-mergetime" datetime="2019-04-10T12:12:42+00:00">10.04.19, 12:12</time></span></span><br>
То есть это мало того что write-only-код, так он еще и не даст заскучать процессору на массивах чуть больше игрушечных размеров. При N элементах N вызовов функции + M (M - количество уникальных элементов) выделений нового массива с копированием элементов и удалений прежнего. В общем, ответ на вопрос, почему компы имеют 3 ГГц процы и 16 Гб оперативы, а браузер с одной вкладкой по-прежнему тормозит]]></description>
        <author>Fr0sT</author>
        <category>Delphi: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3795259</guid>
        <pubDate>Wed, 10 Apr 2019 07:43:16 +0000</pubDate>
        <title>Spring4D</title>
        <link>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3795259</link>
        <description><![CDATA[Cfon: Возращаемся к посту #16 <br>
Предположим у нас добавился рейтинг рецептов, шо делать?  :o <br>
Фигня если код нормально писан то изи :D  зерте шо я делаю  :D <br>
Сначало изменяю TRecipe <br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">type</div><div class="code_line">&nbsp;&nbsp;TRecipe = record</div><div class="code_line">&nbsp;&nbsp; &nbsp;Id: integer;</div><div class="code_line">&nbsp;&nbsp; &nbsp;RecipeName: string;</div><div class="code_line">&nbsp;&nbsp; &nbsp;Ingredients: IList&#60;TIngredient&#62;;</div><div class="code_line">&nbsp;&nbsp; &nbsp;Steps: IList&#60;string&#62;;</div><div class="code_line">&nbsp;&nbsp; &nbsp;Rating: integer; &nbsp; //&#60;-- 1</div><div class="code_line">&nbsp;&nbsp; &nbsp;constructor Create(AId: integer; ARecipeName: string;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;AIngredients: IList&#60;TIngredient&#62;; ASteps: IList&#60;string&#62;; ARating: integer);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // ^^^ 2</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;</div><div class="code_line">{ TRecipe }</div><div class="code_line">&nbsp;</div><div class="code_line">constructor TRecipe.Create(AId: integer; ARecipeName: string;</div><div class="code_line">&nbsp;&nbsp;AIngredients: IList&#60;TIngredient&#62;; ASteps: IList&#60;string&#62;; ARating: integer);</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;Id:= AId;</div><div class="code_line">&nbsp;&nbsp;RecipeName:= ARecipeName;</div><div class="code_line">&nbsp;&nbsp;Ingredients:= AIngredients;</div><div class="code_line">&nbsp;&nbsp;Steps:= ASteps;</div><div class="code_line">&nbsp;&nbsp;Rating:= ARating; //&#60;-- 3</div><div class="code_line">end;</div></ol></div></div></div></div><br>
Далее изменяю метод парсинга JSON CreateRecipes, тут ващ изичи :D<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">.....</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;for var vRecipe in vRecipes do</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;var id:= vRecipe.GetValue&#60;integer&#62;(&#39;id&#39;);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;var name:= vRecipe.GetValue&#60;string&#62;(&#39;name&#39;);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;var vIngrs := vRecipe.GetValue&#60;TJSONArray&#62;(&#39;ingredients&#39;);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;var vSteps := vRecipe.GetValue&#60;TJSONArray&#62;(&#39;steps&#39;);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;var ingredients:= TCollections.CreateList&#60;TIngredient&#62;;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;var steps:= TCollections.CreateList&#60;string&#62;;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;var rating:= &nbsp;vRecipe.GetValue&#60;integer&#62;(&#39;rating&#39;); //&#60;-- 4</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;.....</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Result.Add(TRecipe.Create(id, name, ingredients, steps, rating));</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// ^^^ 5</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;end;</div><div class="code_line">.....</div></ol></div></div></div></div><br>
тестируем<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;// load json file.</div><div class="code_line">&nbsp;&nbsp;var s:= LoadFile(&#39;recipes.json&#39;);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// create recipes list.</div><div class="code_line">&nbsp;&nbsp;var recipes: IList&#60;TRecipe&#62; := CreateRecipes(s);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// query: recipe name and rating list</div><div class="code_line">&nbsp;&nbsp; var query := TEnumerable.Select&#60;TRecipe, string&#62;(recipes,</div><div class="code_line">&nbsp;&nbsp; &nbsp;function (recipe: TRecipe): string</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Result:= Format(&#39;Recipe: %s, Rating: %d&#39;, [recipe.RecipeName, recipe.Rating]);</div><div class="code_line">&nbsp;&nbsp; &nbsp;end</div><div class="code_line">&nbsp;&nbsp;);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// test</div><div class="code_line">&nbsp;&nbsp;query.ForEach(procedure (const s: string)</div><div class="code_line">&nbsp;&nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp;Writeln(s);</div><div class="code_line">&nbsp;&nbsp;end);</div><div class="code_line">&nbsp;</div><div class="code_line">// Recipe: Baked Salmon, Rating: 3</div><div class="code_line">// Recipe: Fish Tacos, Rating: 5</div><div class="code_line">// Recipe: Checken Noodle Soup, Rating: 0</div><div class="code_line">end.</div></ol></div></div></div></div><br>
ВСЕ&#33; :blush:]]></description>
        <author>Cfon</author>
        <category>Delphi: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3795250</guid>
        <pubDate>Wed, 10 Apr 2019 06:12:17 +0000</pubDate>
        <title>Spring4D</title>
        <link>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3795250</link>
        <description><![CDATA[Cfon: <div class='tag-quote'><a class='tag-quote-link' href='https://forum.sources.ru/index.php?showtopic=414484&view=findpost&p=3795185'><span class='tag-quote-prefix'>Цитата</span></a> <span class='tag-quote__quote-info'>jack128 &#064; <time class="tag-quote__quoted-time" datetime="2019-04-09T19:38:51+00:00">09.04.19, 19:38</time></span><div class='quote '><div class='tag-quote'><a class='tag-quote-link' href='https://forum.sources.ru/index.php?showtopic=414484&view=findpost&p=3795182'><span class='tag-quote-prefix'>Цитата</span></a> <span class='tag-quote__quote-info'>Cfon &#064; <time class="tag-quote__quoted-time" datetime="2019-04-09T18:04:35+00:00">09.04.19, 18:04</time></span><div class='quote '>Ну тут все просто, Enumerable&lt;string&gt; не предоставляет метод IndexOf как в примере JS</div></div><br>
А Contains у него есть</div></div><br>
О не заметил :D <br>
Тогда буде даже лучше если вернуть Enumerable&lt;string&gt;, ибо его нельзя никак изменить только копирование:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;var colors := Enumerable&#60;string&#62;.Create([&#39;red&#39;, &#39;red&#39;, &#39;green&#39;, &#39;blue&#39;, &#39;green&#39;]);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;var distinctColors := colors.Aggregate&#60;Enumerable&#60;string&#62;&#62;(</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;TCollections.CreateList&#60;string&#62;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;function (distinct: Enumerable&#60;string&#62;; color: string): Enumerable&#60;string&#62;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Result:= distinct;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;if not distinct.Contains(color) then</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;begin</div><div class="code_line">// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Result.Add(color); //&#60;-- никак не изменить Enumerable только копирование</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Result:= Enumerable&#60;string&#62;.Create(distinct.ToArray + [color]);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;end;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;end);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// test</div><div class="code_line">&nbsp;&nbsp;distinctColors.ForEach(procedure (const s: string)</div><div class="code_line">&nbsp;&nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp;Write(s, &#39;, &#39;);</div><div class="code_line">&nbsp;&nbsp;end);</div><div class="code_line">&nbsp;&nbsp;// red, green, blue,</div><div class="code_line">end;</div></ol></div></div></div></div><br>
Правда мы тут имеем лишнее копирование массива distinct.ToArray, но подругому никак :D<br>
Возможно Enumerable это дело как то оптимизирует и на самом деле ничего не копируется  :D<br>
<br>
Кста у Enumerable есть метод Distint, так шо данный код можно заменить на простой<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">colors:= Enumerable&#60;string&#62;.Create([&#39;red&#39;, &#39;red&#39;, &#39;green&#39;, &#39;blue&#39;, &#39;green&#39;]);</div><div class="code_line">distinctColors:= colors.Distinct;</div></ol></div></div></div></div><br>
но суть примера показать как работает Aggregate&lt;TAccumulate&gt;.<br>
<br>
Далее тут я опять передал в качестве сида (seed) IList&lt;string&gt;  :D<br>
это не опечатка, Enumerable&lt;T&gt; имеет оператор Implicit, который выполняет неявное преобразование типа.]]></description>
        <author>Cfon</author>
        <category>Delphi: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3795185</guid>
        <pubDate>Tue, 09 Apr 2019 19:38:51 +0000</pubDate>
        <title>Spring4D</title>
        <link>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3795185</link>
        <description><![CDATA[jack128: <div class='tag-quote'><a class='tag-quote-link' href='https://forum.sources.ru/index.php?showtopic=414484&view=findpost&p=3795182'><span class='tag-quote-prefix'>Цитата</span></a> <span class='tag-quote__quote-info'>Cfon &#064; <time class="tag-quote__quoted-time" datetime="2019-04-09T18:04:35+00:00">09.04.19, 18:04</time></span><div class='quote '>Ну тут все просто, Enumerable&lt;string&gt; не предоставляет метод IndexOf как в примере JS</div></div><br>
А Contains у него есть]]></description>
        <author>jack128</author>
        <category>Delphi: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3795182</guid>
        <pubDate>Tue, 09 Apr 2019 18:04:35 +0000</pubDate>
        <title>Spring4D</title>
        <link>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3795182</link>
        <description><![CDATA[Cfon: <div class='tag-quote'><a class='tag-quote-link' href='https://forum.sources.ru/index.php?showtopic=414484&view=findpost&p=3795150'><span class='tag-quote-prefix'>Цитата</span></a> <span class='tag-quote__quote-info'>Cfon &#064; <time class="tag-quote__quoted-time" datetime="2019-04-09T12:08:05+00:00">09.04.19, 12:08</time></span><div class='quote '>Задание&#33;  :whistle:  <br>
Надо перенести на Delphi. Кто не понел это код JS  :D <br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">const colors = [&quot;red&quot;, &quot;red&quot;, &quot;green&quot;, &quot;blue&quot;, &quot;green&quot;];</div><div class="code_line">const distinctColors = colors.reduce(</div><div class="code_line">&nbsp;&nbsp;(distinct, color) =&#62; </div><div class="code_line">&nbsp;&nbsp; &nbsp;(distinct.indexOf(color) !== -1) ? </div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;distinct : </div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;[...distinct, color],</div><div class="code_line">[]);</div><div class="code_line">&nbsp;</div><div class="code_line">console.log(distinctColors);</div><div class="code_line">// [&quot;red&quot;, &quot;green&quot;, &quot;blue&quot;]</div></ol></div></div></div></div></div></div><br>
на самом деле это задание средней сложности.<br>
ща разбермся почему, смотрите вот что у меня получилось<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;var colors:= Enumerable&#60;string&#62;.Create([&#39;red&#39;, &#39;red&#39;, &#39;green&#39;, &#39;blue&#39;, &#39;green&#39;]);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;var distinctColors := colors.Aggregate&#60;IList&#60;string&#62;&#62;(</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;TCollections.CreateList&#60;string&#62;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;function (distinct: IList&#60;string&#62;; color: string): IList&#60;string&#62;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Result:= distinct;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;if distinct.IndexOf(color) = -1 then</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Result:= TCollections.CreateList&#60;string&#62;(distinct);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Result.Add(color);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;end;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;end);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// test</div><div class="code_line">&nbsp;&nbsp;distinctColors.ForEach(procedure (const s: string)</div><div class="code_line">&nbsp;&nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp;Writeln(s, &#39;, &#39;);</div><div class="code_line">&nbsp;&nbsp;end);</div><div class="code_line">&nbsp;&nbsp;// red, green, blue,</div><div class="code_line">end.</div></ol></div></div></div></div><br>
тут много чего интересного...<br>
Во первых Aggregate вызывается из объекта colors, который является записью Enumerable. Enumerable предоставлят реализации большого набора методов, в том числе Aggregate&lt;TAccumulate&gt;, реализации которой нет в других структурах данных таких как TList&lt;T&gt; и тд. Поэтому не получится создать например список и обратится к Aggregate&lt;TAccumulate&gt;, его там нет. <br>
Во-вторых колбэк (анонимка) возвращает копию списка, а не ссылку не исходный список. Тоже происходит и в коде на JS каждый раз возвращается копия массива:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">[...distinct, color]</div></ol></div></div></div></div><br>
а так в ДелФи, пока не придумали синтаксис по короче :D <br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">Result:= TCollections.CreateList&#60;string&#62;(distinct);</div><div class="code_line">Result.Add(color);</div></ol></div></div></div></div><br>
Зачем это надо? Это создает более безопасный код, следуя одному из принципов функционального программирования - неизменяемости данных, например:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;var colors:= Enumerable&#60;string&#62;.Create([&#39;red&#39;, &#39;red&#39;, &#39;green&#39;, &#39;blue&#39;, &#39;green&#39;]);</div><div class="code_line">&nbsp;&nbsp;var colors2:= TCollections.CreateList&#60;string&#62;;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;var distinctColors := colors.Aggregate&#60;IList&#60;string&#62;&#62;(</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;colors2, //&#60;--- передаем я качестве начального значения colors2</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;function (distinct: IList&#60;string&#62;; color: string): IList&#60;string&#62;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Result:= distinct;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;if distinct.IndexOf(color) = -1 then</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Result.Add(color); //&#60;-- изменяем непосредствено colors2</div><div class="code_line">// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Result:= TCollections.CreateList&#60;string&#62;(distinct);</div><div class="code_line">// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Result.Add(color);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;end;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;end);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// меняем список colors2</div><div class="code_line">&nbsp;&nbsp;colors2.AddRange([&#39;white&#39;,&#39;black&#39;]);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// test</div><div class="code_line">&nbsp;&nbsp;distinctColors.ForEach(procedure (const s: string)</div><div class="code_line">&nbsp;&nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp;Write(s, &#39;, &#39;);</div><div class="code_line">&nbsp;&nbsp;end);</div><div class="code_line">&nbsp;&nbsp;// red, green, blue, white, black,</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;writeln;</div><div class="code_line">&nbsp;&nbsp;// test</div><div class="code_line">&nbsp;&nbsp;colors2.ForEach(procedure (const s: string)</div><div class="code_line">&nbsp;&nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp;Writeln(s);</div><div class="code_line">&nbsp;&nbsp;end);</div><div class="code_line">&nbsp;&nbsp;// red, green, blue, white, black, &nbsp;</div><div class="code_line">end.</div></ol></div></div></div></div><br>
и что мы видим изменения colors2 повлияли на distinctColors&#33; Их содержимое одинаковое. Это как вы понимаете может в более сложных случаях внести баг, который сложно обнаружить. <br>
Собствено на этом все. Там еще может возникнуть вопрос почему возвращал IList&lt;string&gt;, а не Enumerable&lt;string&gt;? Ну тут все просто, Enumerable&lt;string&gt; не предоставляет метод IndexOf как в примере JS :D]]></description>
        <author>Cfon</author>
        <category>Delphi: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3795160</guid>
        <pubDate>Tue, 09 Apr 2019 13:04:08 +0000</pubDate>
        <title>Spring4D</title>
        <link>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3795160</link>
        <description><![CDATA[Cfon: До этого мы юзали даные вшитые в код, давайте расширим горизонты  :D <br>
Пример Spring4D с данными из JSON файла, большую часть примера занял код парсинга JSON :D<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">uses</div><div class="code_line">&nbsp;&nbsp;System.Classes, System.SysUtils, System.Generics.Collections, System.JSON,</div><div class="code_line">&nbsp;&nbsp;Spring.Collections, Spring.Collections.Enumerable;</div><div class="code_line">&nbsp;</div><div class="code_line">type</div><div class="code_line">&nbsp;&nbsp;TIngredient = record</div><div class="code_line">&nbsp;&nbsp; &nbsp;IngredientName: string;</div><div class="code_line">&nbsp;&nbsp; &nbsp;Amount: Single;</div><div class="code_line">&nbsp;&nbsp; &nbsp;Measurement: string;</div><div class="code_line">&nbsp;&nbsp; &nbsp;constructor Create(AIngredientName: string; AAmount: Single; AMeasurement: string);</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;TRecipe = record</div><div class="code_line">&nbsp;&nbsp; &nbsp;Id: integer;</div><div class="code_line">&nbsp;&nbsp; &nbsp;RecipeName: string;</div><div class="code_line">&nbsp;&nbsp; &nbsp;Ingredients: IList&#60;TIngredient&#62;;</div><div class="code_line">&nbsp;&nbsp; &nbsp;Steps: IList&#60;string&#62;;</div><div class="code_line">&nbsp;&nbsp; &nbsp;constructor Create(AId: integer; ARecipeName: string;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;AIngredients: IList&#60;TIngredient&#62;; ASteps: IList&#60;string&#62;);</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;</div><div class="code_line">{ TRecipe }</div><div class="code_line">&nbsp;</div><div class="code_line">constructor TRecipe.Create(AId: integer; ARecipeName: string;</div><div class="code_line">&nbsp;&nbsp;AIngredients: IList&#60;TIngredient&#62;; ASteps: IList&#60;string&#62;);</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;Id:= AId;</div><div class="code_line">&nbsp;&nbsp;RecipeName:= ARecipeName;</div><div class="code_line">&nbsp;&nbsp;Ingredients:= AIngredients;</div><div class="code_line">&nbsp;&nbsp;Steps:= ASteps;</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">{ TIngredient }</div><div class="code_line">&nbsp;</div><div class="code_line">constructor TIngredient.Create(AIngredientName: string; AAmount: Single;</div><div class="code_line">&nbsp;&nbsp;AMeasurement: string);</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;IngredientName:= AIngredientName;</div><div class="code_line">&nbsp;&nbsp;Amount:= AAmount;</div><div class="code_line">&nbsp;&nbsp;Measurement:= AMeasurement;</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">function LoadFile(fileName: string): string;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;var reader:= TStreamReader.Create(fileName);</div><div class="code_line">&nbsp;&nbsp;try</div><div class="code_line">&nbsp;&nbsp; &nbsp;Result:= reader.ReadToEnd;</div><div class="code_line">&nbsp;&nbsp;finally</div><div class="code_line">&nbsp;&nbsp; &nbsp;reader.Free;</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">function CreateRecipes(json: string): IList&#60;TRecipe&#62;;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;Result:= TCollections.CreateList&#60;TRecipe&#62;;</div><div class="code_line">&nbsp;&nbsp;try</div><div class="code_line">&nbsp;&nbsp; &nbsp;var Root: TJSONValue := TJSONObject.ParseJSONValue(json);</div><div class="code_line">&nbsp;&nbsp; &nbsp;var vRecipes := Root.GetValue&#60;TJSONArray&#62;(&#39;recipes&#39;);</div><div class="code_line">&nbsp;&nbsp; &nbsp;try</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;for var vRecipe in vRecipes do</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;var id:= vRecipe.GetValue&#60;integer&#62;(&#39;id&#39;);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;var name:= vRecipe.GetValue&#60;string&#62;(&#39;name&#39;);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;var vIngrs := vRecipe.GetValue&#60;TJSONArray&#62;(&#39;ingredients&#39;);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;var vSteps := vRecipe.GetValue&#60;TJSONArray&#62;(&#39;steps&#39;);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;var ingredients:= TCollections.CreateList&#60;TIngredient&#62;;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;var steps:= TCollections.CreateList&#60;string&#62;;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;for var vIngr in vIngrs do</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;var ingr:= TIngredient.Create(</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;vIngr.GetValue&#60;string&#62;(&#39;name&#39;),</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;vIngr.GetValue&#60;Single&#62;(&#39;amount&#39;),</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;vIngr.GetValue&#60;string&#62;(&#39;measurement&#39;)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ingredients.Add(ingr);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;end;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;for var vStep in vSteps do</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;steps.Add(vStep.Value);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;end;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Result.Add(TRecipe.Create(id, name, ingredients, steps));</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;end;</div><div class="code_line">&nbsp;&nbsp; &nbsp;finally</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;vRecipes.Free;</div><div class="code_line">&nbsp;&nbsp; &nbsp;end;</div><div class="code_line">&nbsp;&nbsp;except</div><div class="code_line">&nbsp;&nbsp; &nbsp;on E: EJSONException do</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Writeln(&#39;Error parsing JSON. Check file format.&#39;);</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;// load json file.</div><div class="code_line">&nbsp;&nbsp;var s:= LoadFile(&#39;recipes.json&#39;);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// create recipes list.</div><div class="code_line">&nbsp;&nbsp;var recipes: IList&#60;TRecipe&#62; := CreateRecipes(s);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// query: recipe name list</div><div class="code_line">&nbsp;&nbsp;var query := TEnumerable.Select&#60;TRecipe, string&#62;(recipes,</div><div class="code_line">&nbsp;&nbsp; &nbsp;function (recipe: TRecipe): string</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Result:= recipe.RecipeName;</div><div class="code_line">&nbsp;&nbsp; &nbsp;end</div><div class="code_line">&nbsp;&nbsp;);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// print the results.</div><div class="code_line">&nbsp;&nbsp;query.ForEach(procedure (const s: string)</div><div class="code_line">&nbsp;&nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp;Writeln(s);</div><div class="code_line">&nbsp;&nbsp;end);</div><div class="code_line">end.</div></ol></div></div></div></div><br>
часть recipe.json:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">{&quot;recipes&quot;: [{</div><div class="code_line">&nbsp;&nbsp;&quot;id&quot;: 1,</div><div class="code_line">&nbsp;&nbsp;&quot;name&quot;: &quot;Baked Salmon&quot;,</div><div class="code_line">&nbsp;&nbsp;&quot;ingredients&quot;: [{</div><div class="code_line">&nbsp;&nbsp; &nbsp;&quot;name&quot;: &quot;Salmon&quot;,</div><div class="code_line">&nbsp;&nbsp; &nbsp;&quot;amount&quot;: 1,</div><div class="code_line">&nbsp;&nbsp; &nbsp;&quot;measurement&quot;: &quot;lb&quot;</div><div class="code_line">&nbsp;&nbsp;}, {</div><div class="code_line">&nbsp;&nbsp; &nbsp;&quot;name&quot;: &quot;Pine Nuts&quot;,</div><div class="code_line">&nbsp;&nbsp; &nbsp;&quot;amount&quot;: 1,</div><div class="code_line">&nbsp;&nbsp; &nbsp;&quot;measurement&quot;: &quot;cup&quot;</div><div class="code_line">&nbsp;&nbsp;}, {</div><div class="code_line">&nbsp;&nbsp; &nbsp;&quot;name&quot;: &quot;Butter Lettuce&quot;,</div><div class="code_line">&nbsp;&nbsp; &nbsp;&quot;amount&quot;: 2,</div><div class="code_line">&nbsp;&nbsp; &nbsp;&quot;measurement&quot;: &quot;cups&quot;</div><div class="code_line">&nbsp;&nbsp;}, {</div><div class="code_line">&nbsp;&nbsp; &nbsp;&quot;name&quot;: &quot;Yellow Squash&quot;,</div><div class="code_line">&nbsp;&nbsp; &nbsp;&quot;amount&quot;: 1,</div><div class="code_line">&nbsp;&nbsp; &nbsp;&quot;measurement&quot;: &quot;med&quot;</div><div class="code_line">&nbsp;&nbsp;}, {</div><div class="code_line">&nbsp;&nbsp; &nbsp;&quot;name&quot;: &quot;Olive Oil&quot;,</div><div class="code_line">&nbsp;&nbsp; &nbsp;&quot;amount&quot;: 0.5,</div><div class="code_line">&nbsp;&nbsp; &nbsp;&quot;measurement&quot;: &quot;cup&quot;</div><div class="code_line">&nbsp;&nbsp;}, {</div><div class="code_line">&nbsp;&nbsp; &nbsp;&quot;name&quot;: &quot;Garlic&quot;,</div><div class="code_line">&nbsp;&nbsp; &nbsp;&quot;amount&quot;: 3,</div><div class="code_line">&nbsp;&nbsp; &nbsp;&quot;measurement&quot;: &quot;cloves&quot;</div><div class="code_line">&nbsp;&nbsp;}],</div><div class="code_line">&nbsp;&nbsp;&quot;steps&quot;: [</div><div class="code_line">&nbsp;&nbsp; &nbsp;&quot;Preheat the oven to 350 degrees&quot;,</div><div class="code_line">&nbsp;&nbsp; &nbsp;&quot;Spread the olive oil around a glass baking dish.&quot;,</div><div class="code_line">&nbsp;&nbsp; &nbsp;&quot;Add the salmon, garlic, and pine nuts to the dish.&quot;,</div><div class="code_line">&nbsp;&nbsp; &nbsp;&quot;Bake for 15 minutes.&quot;,</div><div class="code_line">&nbsp;&nbsp; &nbsp;&quot;Add the yellow squash and put back in the oven for 30 minutes.&quot;,</div><div class="code_line">&nbsp;&nbsp; &nbsp;&quot;Remove from oven and let cool for 15 minutes. Add the lettuce and serve.&quot;</div><div class="code_line">&nbsp;&nbsp;]</div><div class="code_line">}, {</div><div class="code_line">&nbsp;&nbsp;&quot;id&quot;: 2,</div><div class="code_line">&nbsp;&nbsp;&quot;name&quot;: &quot;Fish Tacos&quot;,</div><div class="code_line">&nbsp;&nbsp;&quot;ingredients&quot;: [{</div><div class="code_line">&nbsp;&nbsp; &nbsp;&quot;name&quot;: &quot;Whitefish&quot;,</div><div class="code_line">&nbsp;&nbsp; &nbsp;&quot;amount&quot;: 1,</div><div class="code_line">&nbsp;&nbsp; &nbsp;&quot;measurement&quot;: &quot;lb&quot;</div><div class="code_line">&nbsp;&nbsp;}, {</div><div class="code_line">&nbsp;&nbsp; &nbsp;&quot;name&quot;: &quot;Cheese&quot;,</div><div class="code_line">&nbsp;&nbsp; &nbsp;&quot;amount&quot;: 1,</div><div class="code_line">&nbsp;&nbsp; &nbsp;&quot;measurement&quot;: &quot;cup&quot;</div><div class="code_line">&nbsp;&nbsp;}, {</div><div class="code_line">&nbsp;&nbsp; &nbsp;&quot;name&quot;: &quot;Iceberg Lettuce&quot;,</div><div class="code_line">&nbsp;&nbsp; &nbsp;&quot;amount&quot;: 2,</div><div class="code_line">&nbsp;&nbsp; &nbsp;&quot;measurement&quot;: &quot;cups&quot;</div><div class="code_line">&nbsp;&nbsp;}, {</div><div class="code_line">&nbsp;&nbsp; &nbsp;&quot;name&quot;: &quot;Tomatoes&quot;,</div><div class="code_line">&nbsp;&nbsp; &nbsp;&quot;amount&quot;: 2,</div><div class="code_line">&nbsp;&nbsp; &nbsp;&quot;measurement&quot;: &quot;large&quot;</div><div class="code_line">&nbsp;&nbsp;}, {</div><div class="code_line">&nbsp;&nbsp; &nbsp;&quot;name&quot;: &quot;Tortillas&quot;,</div><div class="code_line">&nbsp;&nbsp; &nbsp;&quot;amount&quot;: 3,</div><div class="code_line">&nbsp;&nbsp; &nbsp;&quot;measurement&quot;: &quot;med&quot;</div><div class="code_line">&nbsp;&nbsp;}],</div><div class="code_line">&nbsp;&nbsp;&quot;steps&quot;: [</div><div class="code_line">&nbsp;&nbsp; &nbsp;&quot;Cook the fish on the grill until hot.&quot;,</div><div class="code_line">&nbsp;&nbsp; &nbsp;&quot;Place the fish on the 3 tortillas.&quot;,</div><div class="code_line">&nbsp;&nbsp; &nbsp;&quot;Top them with lettuce, tomatoes, and cheese.&quot;</div><div class="code_line">&nbsp;&nbsp;]</div><div class="code_line">}, {</div><div class="code_line">&nbsp;&nbsp;&quot;id&quot;: 3,</div><div class="code_line">&nbsp;&nbsp;&quot;name&quot;: &quot;Checken Noodle Soup&quot;,</div><div class="code_line">&nbsp;&nbsp;&quot;ingredients&quot;: [{</div><div class="code_line">&nbsp;&nbsp; &nbsp;&quot;name&quot;: &quot;Extra-virgin olive oil&quot;,</div><div class="code_line">&nbsp;&nbsp; &nbsp;&quot;amount&quot;: 2,</div><div class="code_line">&nbsp;&nbsp; &nbsp;&quot;measurement&quot;: &quot;tablespoons&quot;</div><div class="code_line">&nbsp;&nbsp;}, {</div><div class="code_line">&nbsp;&nbsp; &nbsp;&quot;name&quot;: &quot;Yello Onion&quot;,</div><div class="code_line">&nbsp;&nbsp; &nbsp;&quot;amount&quot;: 1,</div><div class="code_line">&nbsp;&nbsp; &nbsp;&quot;measurement&quot;: &quot;&quot;</div><div class="code_line">&nbsp;&nbsp;}, {</div><div class="code_line">&nbsp;&nbsp; &nbsp;&quot;name&quot;: &quot;Carrots&quot;,</div><div class="code_line">&nbsp;&nbsp; &nbsp;&quot;amount&quot;: 2,</div><div class="code_line">&nbsp;&nbsp; &nbsp;&quot;measurement&quot;: &quot;meduim&quot;</div><div class="code_line">&nbsp;&nbsp;}, {</div><div class="code_line">&nbsp;&nbsp; &nbsp;&quot;name&quot;: &quot;Celery&quot;,</div><div class="code_line">&nbsp;&nbsp; &nbsp;&quot;amount&quot;: 2,</div><div class="code_line">&nbsp;&nbsp; &nbsp;&quot;measurement&quot;: &quot;stalks&quot;</div><div class="code_line">&nbsp;&nbsp;}, {</div><div class="code_line">&nbsp;&nbsp; &nbsp;&quot;name&quot;: &quot;Chiken Broth&quot;,</div><div class="code_line">&nbsp;&nbsp; &nbsp;&quot;amount&quot;: 8,</div><div class="code_line">&nbsp;&nbsp; &nbsp;&quot;measurement&quot;: &quot;cups&quot;</div><div class="code_line">&nbsp;&nbsp;}, {</div><div class="code_line">&nbsp;&nbsp; &nbsp;&quot;name&quot;: &quot;Wide Egg Noodles&quot;,</div><div class="code_line">&nbsp;&nbsp; &nbsp;&quot;amount&quot;: 1,</div><div class="code_line">&nbsp;&nbsp; &nbsp;&quot;measurement&quot;: &quot;package&quot;</div><div class="code_line">&nbsp;&nbsp;}, {</div><div class="code_line">&nbsp;&nbsp; &nbsp;&quot;name&quot;: &quot;Cooked Chicken&quot;,</div><div class="code_line">&nbsp;&nbsp; &nbsp;&quot;amount&quot;: 1,</div><div class="code_line">&nbsp;&nbsp; &nbsp;&quot;measurement&quot;: &quot;cup&quot;</div><div class="code_line">&nbsp;&nbsp;}],</div><div class="code_line">&nbsp;&nbsp;&quot;steps&quot;: [</div><div class="code_line">&nbsp;&nbsp; &nbsp;&quot;Chop and saute onion, carrots, and celery in olive oil until soft.&quot;,</div><div class="code_line">&nbsp;&nbsp; &nbsp;&quot;Add chicken &nbsp;broth and bring to boil.&quot;,</div><div class="code_line">&nbsp;&nbsp; &nbsp;&quot;Add egg noodles and cook until soft.&quot;,</div><div class="code_line">&nbsp;&nbsp; &nbsp;&quot;Add chicken and simmer.&quot;</div><div class="code_line">&nbsp;&nbsp;]</div><div class="code_line">}]}</div></ol></div></div></div></div><br>
Теперь можно вдоволь попрактиковаться в запросах]]></description>
        <author>Cfon</author>
        <category>Delphi: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3795150</guid>
        <pubDate>Tue, 09 Apr 2019 12:08:05 +0000</pubDate>
        <title>Spring4D</title>
        <link>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3795150</link>
        <description><![CDATA[Cfon: Задание&#33;  :whistle:  <br>
Надо перенести на Delphi. Кто не понел это код JS  :D <br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">const colors = [&quot;red&quot;, &quot;red&quot;, &quot;green&quot;, &quot;blue&quot;, &quot;green&quot;];</div><div class="code_line">const distinctColors = colors.reduce(</div><div class="code_line">&nbsp;&nbsp;(distinct, color) =&#62; </div><div class="code_line">&nbsp;&nbsp; &nbsp;(distinct.indexOf(color) !== -1) ? </div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;distinct : </div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;[...distinct, color],</div><div class="code_line">[]);</div><div class="code_line">&nbsp;</div><div class="code_line">console.log(distinctColors);</div><div class="code_line">// [&quot;red&quot;, &quot;green&quot;, &quot;blue&quot;]</div></ol></div></div></div></div>]]></description>
        <author>Cfon</author>
        <category>Delphi: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3795019</guid>
        <pubDate>Mon, 08 Apr 2019 08:30:20 +0000</pubDate>
        <title>Spring4D</title>
        <link>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3795019</link>
        <description><![CDATA[Cfon: Уфф чет я завис на селектах  :D <br>
пора продолжать итак пишем Aggregate это аналог Reduce из JS, на сайте С# указаном выше, даны три примера, я их все сразу переложил на делфи:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">uses</div><div class="code_line">&nbsp;&nbsp;System.SysUtils,</div><div class="code_line">&nbsp;&nbsp;Spring.Collections,</div><div class="code_line">&nbsp;&nbsp;Spring.Collections.Enumerable;</div><div class="code_line">&nbsp;</div><div class="code_line">procedure AggregateEx1;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;var ints := TArray&#60;integer&#62;.Create(4, 8, 8, 3, 9, 0, 7, 8, 2);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// Count the even numbers in the array, using a seed value of 0.</div><div class="code_line">&nbsp;&nbsp;var numEven:= Enumerable&#60;integer&#62;.Create(ints).Aggregate&#60;integer&#62;(0,</div><div class="code_line">&nbsp;&nbsp; &nbsp;function(total, next: integer): integer</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Result:= total;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;if next mod 2 = 0 then Result:= total + 1;</div><div class="code_line">&nbsp;&nbsp; &nbsp;end);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;Writeln(&#39;The number of even integers is: &#39;, numEven);</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">{$REGION &#39;C# code&#39;}</div><div class="code_line">// &nbsp;int[] ints = { 4, 8, 8, 3, 9, 0, 7, 8, 2 };</div><div class="code_line">//</div><div class="code_line">// &nbsp;// Count the even numbers in the array, using a seed value of 0.</div><div class="code_line">// &nbsp;int numEven = ints.Aggregate(0, (total, next) =&#62;</div><div class="code_line">// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;next % 2 == 0 ? total + 1 : total);</div><div class="code_line">//</div><div class="code_line">// &nbsp;Console.WriteLine(&quot;The number of even integers is: {0}&quot;, numEven);</div><div class="code_line">{$ENDREGION}</div><div class="code_line">// This code produces the following output:</div><div class="code_line">//</div><div class="code_line">// The number of even integers is: 6</div><div class="code_line">&nbsp;</div><div class="code_line">procedure AggregateEx2;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;var sentence := &#39;the quick brown fox jumps over the lazy dog&#39;;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// Split the string into individual.</div><div class="code_line">&nbsp;&nbsp;var words:= TCollections.CreateList&#60;string&#62;(sentence.Split([&#39; &#39;]));</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// Prepend each word to the beginning of the</div><div class="code_line">&nbsp;&nbsp;// new sentence to reverse the word order.</div><div class="code_line">&nbsp;&nbsp;var reversed:= words.Aggregate(</div><div class="code_line">&nbsp;&nbsp; &nbsp;function (workingSentence, next: string): string</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Result:= next + &#39; &#39; + workingSentence;</div><div class="code_line">&nbsp;&nbsp; &nbsp;end</div><div class="code_line">&nbsp;&nbsp;);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;Writeln(reversed);</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">{$REGION &#39;C# code&#39;}</div><div class="code_line">// string sentence = &quot;the quick brown fox jumps over the lazy dog&quot;;</div><div class="code_line">//</div><div class="code_line">// // Split the string into individual words.</div><div class="code_line">// string[] words = sentence.Split(&#39; &#39;);</div><div class="code_line">//</div><div class="code_line">// // Prepend each word to the beginning of the</div><div class="code_line">// // new sentence to reverse the word order.</div><div class="code_line">// string reversed = words.Aggregate((workingSentence, next) =&#62;</div><div class="code_line">// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;next + &quot; &quot; + workingSentence);</div><div class="code_line">//</div><div class="code_line">// Console.WriteLine(reversed);</div><div class="code_line">{$ENDREGION}</div><div class="code_line">// This code produces the following output:</div><div class="code_line">//</div><div class="code_line">// dog lazy the over jumps fox brown quick the</div><div class="code_line">&nbsp;</div><div class="code_line">procedure AggregateEx3;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;var fruits:= TArray&#60;string&#62;.Create(&#39;apple&#39;, &#39;mango&#39;, &#39;orange&#39;, &#39;passionfruit&#39;, &#39;grape&#39;);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// Determine whether any string in the array is longer than &quot;banana&quot;.</div><div class="code_line">&nbsp;&nbsp;var longestName:= Enumerable&#60;string&#62;.Create(fruits)</div><div class="code_line">&nbsp;&nbsp; &nbsp;.Aggregate&#60;string, string&#62;(&#39;banana&#39;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;function (longest, next:string): string</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Result:= longest;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;if Length(next) &#62; Length(longest) then</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Result:= next;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;end,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;// Return the final result as an upper case string.</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;function (fruit: string): string</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Result:= fruit.ToUpper;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;end);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;Writeln(&#39;The fruit with the longest name is &#39;, longestName);</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">{$REGION &#39;C# code&#39;}</div><div class="code_line">// string[] fruits = { &quot;apple&quot;, &quot;mango&quot;, &quot;orange&quot;, &quot;passionfruit&quot;, &quot;grape&quot; };</div><div class="code_line">//</div><div class="code_line">// // Determine whether any string in the array is longer than &quot;banana&quot;.</div><div class="code_line">// string longestName =</div><div class="code_line">// &nbsp; &nbsp;fruits.Aggregate(&quot;banana&quot;,</div><div class="code_line">// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(longest, next) =&#62;</div><div class="code_line">// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;next.Length &#62; longest.Length ? next : longest,</div><div class="code_line">// &nbsp; &nbsp;// Return the final result as an upper case string.</div><div class="code_line">// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;fruit =&#62; fruit.ToUpper());</div><div class="code_line">//</div><div class="code_line">// Console.WriteLine(</div><div class="code_line">// &nbsp; &nbsp;&quot;The fruit with the longest name is {0}.&quot;,</div><div class="code_line">// &nbsp; &nbsp;longestName);</div><div class="code_line">{$ENDREGION}</div><div class="code_line">// This code produces the following output:</div><div class="code_line">//</div><div class="code_line">// The fruit with the longest name is PASSIONFRUIT.</div><div class="code_line">&nbsp;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;AggregateEx1;</div><div class="code_line">&nbsp;&nbsp;AggregateEx2;</div><div class="code_line">&nbsp;&nbsp;AggregateEx3;</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">end.</div></ol></div></div></div></div><br>
Я также привел код на шарпе, сравнивайте.]]></description>
        <author>Cfon</author>
        <category>Delphi: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3795017</guid>
        <pubDate>Mon, 08 Apr 2019 08:13:26 +0000</pubDate>
        <title>Spring4D</title>
        <link>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3795017</link>
        <description><![CDATA[Cfon: <div class='tag-quote'><a class='tag-quote-link' href='https://forum.sources.ru/index.php?showtopic=414484&view=findpost&p=3794959'><span class='tag-quote-prefix'>Цитата</span></a> <span class='tag-quote__quote-info'>Cfon &#064; <time class="tag-quote__quoted-time" datetime="2019-04-07T05:10:26+00:00">07.04.19, 05:10</time></span><div class='quote '>Дело было в инлайн переменной obj в цикле вывода <br>
переместил ее в раздел объявлений и все&#33;  :D <br>
Гениально&#33;  :lool: <br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;obj: TOwnerNameAndPetName;</div><div class="code_line">begin</div><div class="code_line">...</div><div class="code_line">&nbsp;&nbsp;// Print the results.</div><div class="code_line">&nbsp;&nbsp;for obj in Query do</div><div class="code_line">&nbsp;&nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp;Writeln(Format(&#39;{Owner=%s, Pet=%s}&#39;, [obj.ownerName, obj.petName]));</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">end.</div></ol></div></div></div></div></div></div><br>
Обнаружил еще решения данного косяка:<br>
1- указать тип переменной obj в цикле.<br>
2- вместо класса TPetOwner юзать рекорд.<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">type</div><div class="code_line">&nbsp;&nbsp;TPetOwner = record </div><div class="code_line">&nbsp;&nbsp; &nbsp;Name: string;</div><div class="code_line">&nbsp;&nbsp; &nbsp;Pets: IList&#60;string&#62;;</div><div class="code_line">&nbsp;&nbsp; &nbsp;constructor Create(AName: string; APets: IList&#60;string&#62;);</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;</div><div class="code_line">.....</div><div class="code_line">&nbsp;</div><div class="code_line">begin</div><div class="code_line">.....</div><div class="code_line">&nbsp;&nbsp;// Print the results.</div><div class="code_line">&nbsp;&nbsp;for var obj: TOwnerNameAndPetName in Query do</div><div class="code_line">&nbsp;&nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp;Writeln(Format(&#39;{Owner=%s, Pet=%s}&#39;, [obj.ownerName, obj.petName]));</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">end</div></ol></div></div></div></div> <br>
<br>
<span class="tag-color tag-color-named" data-value="mergepost" style="color: mergepost"><span class='tag-size' data-value='7' style='font-size:7pt;'>Добавлено <time class="tag-mergetime" datetime="2019-04-08T08:19:18+00:00">08.04.19, 08:19</time></span></span><br>
<div class='tag-quote'><a class='tag-quote-link' href='https://forum.sources.ru/index.php?showtopic=414484&view=findpost&p=3794988'><span class='tag-quote-prefix'>Цитата</span></a> <span class='tag-quote__quote-info'>Cfon &#064; <time class="tag-quote__quoted-time" datetime="2019-04-07T18:56:38+00:00">07.04.19, 18:56</time></span><div class='quote '>Давайте закрепим тему  :D <br>
- Вывести список имен владельцев<br>
- Вывести список имен владельцев и количество домашних животных<br>
Это простые запросы, но они позволят нам понять как работает Select.</div></div><br>
Решение  :D <br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;var PetOwners := Enumerable&#60;TPetOwner&#62;.Create([</div><div class="code_line">&nbsp;&nbsp; &nbsp;TPetOwner.Create(&#39;Higa&#39;, TCollections.CreateList&#60;string&#62;([&#39;Scruffy&#39;, &#39;Sam&#39;])),</div><div class="code_line">&nbsp;&nbsp; &nbsp;TPetOwner.Create(&#39;Ashkenazi&#39;,TCollections.CreateList&#60;string&#62;([&#39;Walker&#39;, &#39;Sugar&#39;])),</div><div class="code_line">&nbsp;&nbsp; &nbsp;TPetOwner.Create(&#39;Price&#39;, TCollections.CreateList&#60;string&#62;([&#39;Scratches&#39;, &#39;Diesel&#39;])),</div><div class="code_line">&nbsp;&nbsp; &nbsp;TPetOwner.Create(&#39;Hines&#39;, TCollections.CreateList&#60;string&#62;([&#39;Dusty&#39;]))</div><div class="code_line">&nbsp;&nbsp;]);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;var Query:= PetOwners.Select&#60;string&#62;(</div><div class="code_line">&nbsp;&nbsp; &nbsp;function (owner: TPetOwner): string</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Result:= owner.Name;</div><div class="code_line">&nbsp;&nbsp; &nbsp;end);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;var Query2:= PetOwners.Select&#60;TOwnerNameAndPetCount&#62;(</div><div class="code_line">&nbsp;&nbsp; &nbsp;function (owner: TPetOwner): TOwnerNameAndPetCount</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Result:= TOwnerNameAndPetCount.Create(owner.Name, owner.Pets.Count);</div><div class="code_line">&nbsp;&nbsp; &nbsp;end);</div><div class="code_line">end;</div></ol></div></div></div></div>]]></description>
        <author>Cfon</author>
        <category>Delphi: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3794988</guid>
        <pubDate>Sun, 07 Apr 2019 18:56:38 +0000</pubDate>
        <title>Spring4D</title>
        <link>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3794988</link>
        <description><![CDATA[Cfon: Давайте закрепим тему  :D <br>
- Вывести список имен владельцев<br>
- Вывести список имен владельцев и количество домашних животных<br>
Это простые запросы, но они позволят нам понять как работает Select.<br>
Данные те же список TPetOwner:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">PetOwners := TCollections.CreateList&#60;TPetOwner&#62;([</div><div class="code_line">&nbsp;&nbsp; &nbsp;TPetOwner.Create(&#39;Higa&#39;, TCollections.CreateList&#60;string&#62;([&#39;Scruffy&#39;, &#39;Sam&#39;])),</div><div class="code_line">&nbsp;&nbsp; &nbsp;TPetOwner.Create(&#39;Ashkenazi&#39;, TCollections.CreateList&#60;string&#62;([&#39;Walker&#39;, &#39;Sugar&#39;])),</div><div class="code_line">&nbsp;&nbsp; &nbsp;TPetOwner.Create(&#39;Price&#39;, TCollections.CreateList&#60;string&#62;([&#39;Scratches&#39;, &#39;Diesel&#39;])),</div><div class="code_line">&nbsp;&nbsp; &nbsp;TPetOwner.Create(&#39;Hines&#39;, TCollections.CreateList&#60;string&#62;([&#39;Dusty&#39;]))</div><div class="code_line">&nbsp;&nbsp;]);</div></ol></div></div></div></div>]]></description>
        <author>Cfon</author>
        <category>Delphi: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3794970</guid>
        <pubDate>Sun, 07 Apr 2019 11:20:55 +0000</pubDate>
        <title>Spring4D</title>
        <link>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3794970</link>
        <description><![CDATA[Cfon: Немного подробностей о Spring.Collections:<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">IEnumerable&#60;T&#62; = interface(IEnumerable)</div><div class="code_line">ICollection&#60;T&#62; = interface(IEnumerable&#60;T&#62;)</div><div class="code_line">IList&#60;T&#62; = interface(ICollection&#60;T&#62;)</div><div class="code_line">...</div><div class="code_line">IMap&#60;TKey, TValue&#62; = interface(ICollection&#60;TPair&#60;TKey, TValue&#62;&#62;</div><div class="code_line">IDictionary&#60;TKey, TValue&#62; = interface(IMap&#60;TKey, TValue&#62;)</div><div class="code_line">&nbsp;</div><div class="code_line">TCollections = class</div><div class="code_line">TEnumerable = class</div></ol></div></div></div></div><br>
<br>
Отдельно стоит Spring.Collections.Enumerable где определен один элемент:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">Enumerable = record</div></ol></div></div></div></div><br>
TCollections реализует статические методы создания различных структур данных, интерфейсы которых определны выше.<br>
TEnumerable реализует стат. методы обработки этих данных.<br>
Enumerable тоже что и TEnumerable, но тока больше :D<br>
<br>
Теперь некоторые особености реализации моих примеров, например в коде из поста #9 я создаю PetOwners как Enumerable&lt;TPetOwner&gt;, почему?<br>
Потому что так проще заюзать SelectMany, конечно Enumerable&lt;TPetOwner&gt; это не полноценая структура данных таких как TList и другие, но нам их функциональность была не нужена в прмерах, смотрите как это выглядит через TCollections.CreateList:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">// список</div><div class="code_line">&nbsp;&nbsp;var PetOwners := TCollections.CreateList&#60;TPetOwner&#62;([</div><div class="code_line">&nbsp;&nbsp; &nbsp;TPetOwner.Create(&#39;Higa&#39;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;TCollections.CreateList&#60;string&#62;([&#39;Scruffy&#39;, &#39;Sam&#39;])),</div><div class="code_line">&nbsp;&nbsp; &nbsp;TPetOwner.Create(&#39;Ashkenazi&#39;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;TCollections.CreateList&#60;string&#62;([&#39;Walker&#39;, &#39;Sugar&#39;])),</div><div class="code_line">&nbsp;&nbsp; &nbsp;TPetOwner.Create(&#39;Price&#39;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;TCollections.CreateList&#60;string&#62;([&#39;Scratches&#39;, &#39;Diesel&#39;])),</div><div class="code_line">&nbsp;&nbsp; &nbsp;TPetOwner.Create(&#39;Hines&#39;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;TCollections.CreateList&#60;string&#62;([&#39;Dusty&#39;]))</div><div class="code_line">&nbsp;&nbsp;]);</div><div class="code_line">&nbsp;&nbsp;// запрос</div><div class="code_line">&nbsp;&nbsp;var Query := Enumerable&#60;TPetOwner&#62;.Create(PetOwners.ToArray) //&#60;-- создаем</div><div class="code_line">&nbsp;&nbsp; &nbsp;.SelectMany&#60;string&#62;(function(owner: TPetOwner): IEnumerable&#60;string&#62;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Result:= owner.Pets;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;end);</div></ol></div></div></div></div><br>
Один фиг пришлось создать Enumerable&lt;TPetOwner&gt;, чтобы выполнить SelectMany запрос. Сравните<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;var PetOwners := Enumerable&#60;TPetOwner&#62;.Create([</div><div class="code_line">&nbsp;&nbsp; &nbsp;TPetOwner.Create(&#39;Higa&#39;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;TCollections.CreateList&#60;string&#62;([&#39;Scruffy&#39;, &#39;Sam&#39;])),</div><div class="code_line">&nbsp;&nbsp; &nbsp;TPetOwner.Create(&#39;Ashkenazi&#39;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;TCollections.CreateList&#60;string&#62;([&#39;Walker&#39;, &#39;Sugar&#39;])),</div><div class="code_line">&nbsp;&nbsp; &nbsp;TPetOwner.Create(&#39;Price&#39;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;TCollections.CreateList&#60;string&#62;([&#39;Scratches&#39;, &#39;Diesel&#39;])),</div><div class="code_line">&nbsp;&nbsp; &nbsp;TPetOwner.Create(&#39;Hines&#39;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;TCollections.CreateList&#60;string&#62;([&#39;Dusty&#39;]))</div><div class="code_line">&nbsp;&nbsp;]);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;var Query := PetOwners.SelectMany&#60;string&#62;(</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;function (owner: TPetOwner): IEnumerable&#60;string&#62;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Result:= owner.Pets;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;end);</div></ol></div></div></div></div><br>
Проще не так ли? <br>
Ну а если понадобится функции например списка? Нет проблем братишка это изиж   зерь сюда  :D <br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">var listPetOwners := PetOwners.ToList;</div></ol></div></div></div></div><br>
Все дальше работаем как со списком :D<br>
- Хэ а где try finally Free чувачок ах? мемори лик не? <br>
Не братэлу тут у нас интерфесное прогание без всяких Free&#33;<br>
- Как так?<br>
А вот так компиль сам все контролит и когда надо делитит мусор :D <br>
- Фигасе&#33; Клево&#33;<br>
А то&#33; Интерморда рулит&#33;  :lool:<br>
<br>
Упс я чутка поспешил :D <br>
Объекты что хранит Enumerable не удаляются ибо они созданы не через механизм интерфейса, поэтому да их надо ручками удалять например<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">for var ob in PetOwners do</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;ob.Free;</div><div class="code_line">end;</div></ol></div></div></div></div><br>
или чтобы савсем не видет циклы то так  :D <br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">PetOwners.ForEach(procedure (const obj: TPetOwner)</div><div class="code_line">&nbsp;&nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp;obj.Free;</div><div class="code_line">&nbsp;&nbsp;end);</div></ol></div></div></div></div><br>
Ну или юзать методы типа TCollections.CreateObjectList, они по умолчанию сами делитят свое содержимое.<br>
<br>
А можно заюзать интерфес IPetOwner для TPetOwner например<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">type</div><div class="code_line">&nbsp;&nbsp;IPetOwner = interface</div><div class="code_line">&nbsp;&nbsp; &nbsp;function GetName: string;</div><div class="code_line">&nbsp;&nbsp; &nbsp;procedure SetName(AName: string);</div><div class="code_line">&nbsp;&nbsp; &nbsp;function GetPets: IList&#60;string&#62;;</div><div class="code_line">&nbsp;&nbsp; &nbsp;property Name: string read GetName write SetName;</div><div class="code_line">&nbsp;&nbsp; &nbsp;property Pets: IList&#60;string&#62; read GetPets;</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;TPetOwner = class(TInterfacedObject, IPetOwner)</div><div class="code_line">&nbsp;&nbsp;private</div><div class="code_line">&nbsp;&nbsp; &nbsp;FName: string;</div><div class="code_line">&nbsp;&nbsp; &nbsp;FPets: IList&#60;string&#62;;</div><div class="code_line">&nbsp;&nbsp; &nbsp;function GetName: string;</div><div class="code_line">&nbsp;&nbsp; &nbsp;procedure SetName(AName: string);</div><div class="code_line">&nbsp;&nbsp; &nbsp;function GetPets: IList&#60;string&#62;;</div><div class="code_line">&nbsp;&nbsp;public</div><div class="code_line">&nbsp;&nbsp; &nbsp;constructor Create(AName: string; APets: IList&#60;string&#62;);</div><div class="code_line">&nbsp;&nbsp; &nbsp;property Name: string read GetName write SetName;</div><div class="code_line">&nbsp;&nbsp; &nbsp;property Pets: IList&#60;string&#62; read GetPets;</div><div class="code_line">&nbsp;&nbsp;end;</div></ol></div></div></div></div><br>
Там по коду тоже надо заменить TPetOwner на IPetOwner и все вручную уже не надо удалять  :D <br>
Или юзать запись вместо класса их тоже не надо удалять :lool: <br>
<br>
Да и еще одна особеность примеров любое присваивание переменной выполняется один раз&#33; Зачем? <br>
ну это принципы функционального программирования, данные считаются неизмеными воооот... :D <br>
Вот и я для каждого нового состояния юзал отдельную перемнную.]]></description>
        <author>Cfon</author>
        <category>Delphi: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3794959</guid>
        <pubDate>Sun, 07 Apr 2019 05:10:26 +0000</pubDate>
        <title>Spring4D</title>
        <link>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3794959</link>
        <description><![CDATA[Cfon: Дело было в инлайн переменной obj в цикле вывода <br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">.....</div><div class="code_line">&nbsp;&nbsp;// Print the results.</div><div class="code_line">&nbsp;&nbsp;for var obj in Query do</div><div class="code_line">&nbsp;&nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp;Writeln(Format(&#39;{Owner=%s, Pet=%s}&#39;, [obj.ownerName, obj.petName]));</div><div class="code_line">&nbsp;&nbsp;end;</div></ol></div></div></div></div><br>
переместил ее в раздел объявлений и все&#33;  :D <br>
Гениально&#33;  :lool: <br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp;obj: TOwnerNameAndPetName;</div><div class="code_line">begin</div><div class="code_line">...</div><div class="code_line">&nbsp;&nbsp;// Print the results.</div><div class="code_line">&nbsp;&nbsp;for obj in Query do</div><div class="code_line">&nbsp;&nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp;Writeln(Format(&#39;{Owner=%s, Pet=%s}&#39;, [obj.ownerName, obj.petName]));</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">end.</div></ol></div></div></div></div><br>
Как я обнаружил это? Все просто я установил Delphi XE2 ну ту что еще Spring4D поддерживает и так как там нет инлайна я перенес их в раздел объявлений, ну и все вдруг заработало :D <br>
Почему она вылазила тока при замене TOwnerAndPet на TOwnerNameAndPetName я хз, пока не интересно :D <br>
Не стабильно пока работает инлайнинг переменных  :whistle: <br>
ПС. другие инлайны не влияли на ошибку.]]></description>
        <author>Cfon</author>
        <category>Delphi: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3794913</guid>
        <pubDate>Sat, 06 Apr 2019 12:02:16 +0000</pubDate>
        <title>Spring4D</title>
        <link>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3794913</link>
        <description><![CDATA[Cfon: Продолжаю упрощать  :D<br>
Попытался переложить пример из поста #3 на рельсы Enumerable, но получаю ошибку, причем хз откуда она вылазит, дебугер стопица на асм-коде, я там не шарю не стал мучать себя поисками :D <br>
Да на самом деле я сделал еще не большое упрощение кода, удалил последний Select, и сразу возращал массив TOwnerNameAndPetName. Вот тогда и стала вызалить ошибка :D, если переносить один в один то все пучком&#33;  :wacko: <br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">uses</div><div class="code_line">&nbsp;&nbsp;System.SysUtils,</div><div class="code_line">&nbsp;&nbsp;Spring.Collections,</div><div class="code_line">&nbsp;&nbsp;Spring.Collections.Enumerable;</div><div class="code_line">&nbsp;</div><div class="code_line">type</div><div class="code_line">&nbsp;&nbsp;TOwnerNameAndPetName = record</div><div class="code_line">&nbsp;&nbsp; &nbsp;ownerName: string;</div><div class="code_line">&nbsp;&nbsp; &nbsp;petName: string;</div><div class="code_line">&nbsp;&nbsp; &nbsp;constructor Create(AOwnerName: string; APetName: string);</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;</div><div class="code_line">{ TOwnerNameAndPetName }</div><div class="code_line">&nbsp;</div><div class="code_line">constructor TOwnerNameAndPetName.Create(AOwnerName, APetName: string);</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;ownerName:= AOwnerName;</div><div class="code_line">&nbsp;&nbsp;petName:= APetName;</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;var PetOwners := Enumerable&#60;TPetOwner&#62;.Create([</div><div class="code_line">&nbsp;&nbsp; &nbsp;TPetOwner.Create(&#39;Higa&#39;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;TCollections.CreateList&#60;string&#62;([&#39;Scruffy&#39;, &#39;Sam&#39;])),</div><div class="code_line">&nbsp;&nbsp; &nbsp;TPetOwner.Create(&#39;Ashkenazi&#39;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;TCollections.CreateList&#60;string&#62;([&#39;Walker&#39;, &#39;Sugar&#39;])),</div><div class="code_line">&nbsp;&nbsp; &nbsp;TPetOwner.Create(&#39;Price&#39;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;TCollections.CreateList&#60;string&#62;([&#39;Scratches&#39;, &#39;Diesel&#39;])),</div><div class="code_line">&nbsp;&nbsp; &nbsp;TPetOwner.Create(&#39;Hines&#39;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;TCollections.CreateList&#60;string&#62;([&#39;Dusty&#39;]))</div><div class="code_line">&nbsp;&nbsp;]);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;var Query := PetOwners</div><div class="code_line">&nbsp;&nbsp; &nbsp;.SelectMany&#60;string, TOwnerNameAndPetName&#62;(</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;function (owner: TPetOwner): IEnumerable&#60;string&#62;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Result:= owner.Pets;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;end,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;function (owner: TPetOwner; petName: string): TOwnerNameAndPetName</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Result:= TOwnerNameAndPetName.Create(owner.Name, petName);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;end)</div><div class="code_line">&nbsp;&nbsp; &nbsp;.Where(function (const ownerAndPet: TOwnerNameAndPetName): Boolean</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Result:= ownerAndPet.petName.StartsWith(&#39;S&#39;);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;end);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; // тут был Select и его удалил и теперь ошибка</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// Print the results.</div><div class="code_line">&nbsp;&nbsp;for var obj in Query do</div><div class="code_line">&nbsp;&nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp;Writeln(Format(&#39;{Owner=%s, Pet=%s}&#39;, [obj.ownerName, obj.petName]));</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">end.</div></ol></div></div></div></div><br>
Забыл сказать что все компилица, ошибка рантайм.<br>
Если заменить запись TOwnerNameAndPetName на TOwnerAndPet, то все пучком  :wall: <br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">var Query := PetOwners</div><div class="code_line">&nbsp;&nbsp; &nbsp;.SelectMany&#60;string, TOwnerAndPet&#62;(</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;function (owner: TPetOwner): IEnumerable&#60;string&#62;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Result:= owner.Pets;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;end,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;function (owner: TPetOwner; petName: string): TOwnerAndPet</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Result:= TOwnerAndPet.Create(owner, petName);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;end)</div><div class="code_line">&nbsp;&nbsp; &nbsp;.Where(function (const ownerAndPet: TOwnerAndPet): Boolean</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Result:= ownerAndPet.petName.StartsWith(&#39;S&#39;);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;end);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// Print the results.</div><div class="code_line">&nbsp;&nbsp;for var obj in Query do</div><div class="code_line">&nbsp;&nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp;Writeln(Format(&#39;{Owner=%s, Pet=%s}&#39;, [obj.owner.Name, obj.petName]));</div><div class="code_line">&nbsp;&nbsp;end;</div></ol></div></div></div></div><br>
Ошибка в функции System._UStrAsg на асма-строке:<br>
 LOCK DEC     [EDX-skew].StrRec.refCnt<br>
че она делает я хз  :blink:<br>
Я так понел что какие то траблы в работе со строками.<br>
<br>
Опа а если сделать копию PetOwners, то пашет&#33;  :wall: <br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">var Query := Enumerable&#60;TPetOwner&#62;.Create(PetOwners.ToArray)</div><div class="code_line">&nbsp;&nbsp; &nbsp;.SelectMany&#60;string, TOwnerNameAndPetName&#62;(</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;function (owner: TPetOwner): IEnumerable&#60;string&#62;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Result:= owner.Pets;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;end,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;function (owner: TPetOwner; petName: string): TOwnerNameAndPetName</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Result:= TOwnerNameAndPetName.Create(owner.Name, petName);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;end)</div><div class="code_line">&nbsp;&nbsp; &nbsp;.Where(function (const ownerAndPet: TOwnerNameAndPetName): Boolean</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Result:= ownerAndPet.petName.StartsWith(&#39;S&#39;);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;end)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;;</div></ol></div></div></div></div>]]></description>
        <author>Cfon</author>
        <category>Delphi: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3794907</guid>
        <pubDate>Sat, 06 Apr 2019 10:25:40 +0000</pubDate>
        <title>Spring4D</title>
        <link>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3794907</link>
        <description><![CDATA[Cfon: Упрощаем код заюзав модуль Spring.Collections.Enumerable:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">uses</div><div class="code_line">&nbsp;&nbsp;System.SysUtils,</div><div class="code_line">&nbsp;&nbsp;Spring.Collections,</div><div class="code_line">&nbsp;&nbsp;Spring.Collections.Enumerable;</div><div class="code_line">&nbsp;</div><div class="code_line">type</div><div class="code_line">&nbsp;&nbsp;TPetOwner = class</div><div class="code_line">&nbsp;&nbsp; &nbsp;Name: string;</div><div class="code_line">&nbsp;&nbsp; &nbsp;Pets: IList&#60;string&#62;;</div><div class="code_line">&nbsp;&nbsp; &nbsp;constructor Create(AName: string; APets: IList&#60;string&#62;); &nbsp; &nbsp;</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;</div><div class="code_line">{ TPetOwner }</div><div class="code_line">&nbsp;</div><div class="code_line">constructor TPetOwner.Create(AName: string; APets: IList&#60;string&#62;);</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;Name:= AName;</div><div class="code_line">&nbsp;&nbsp;Pets:= APets;</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">begin </div><div class="code_line">&nbsp;&nbsp;var PetOwners := Enumerable&#60;TPetOwner&#62;.Create([</div><div class="code_line">&nbsp;&nbsp; &nbsp; TPetOwner.Create(&#39;Higa, Sidney&#39;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; TCollections.CreateList&#60;string&#62;([&#39;Scruffy&#39;, &#39;Sam&#39;])),</div><div class="code_line">&nbsp;&nbsp; &nbsp; TPetOwner.Create(&#39;Ashkenazi, Ronen&#39;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; TCollections.CreateList&#60;string&#62;([&#39;Walker&#39;, &#39;Sugar&#39;])),</div><div class="code_line">&nbsp;&nbsp; &nbsp; TPetOwner.Create(&#39;Price, Vernette&#39;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; TCollections.CreateList&#60;string&#62;([&#39;Scratches&#39;, &#39;Diesel&#39;]))</div><div class="code_line">&nbsp;&nbsp; ]);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; // Query using SelectMany.</div><div class="code_line">&nbsp;&nbsp; var Query1 := PetOwners.SelectMany&#60;string&#62;(</div><div class="code_line">&nbsp;&nbsp; &nbsp; function (petOwner: TPetOwner): IEnumerable&#60;string&#62;</div><div class="code_line">&nbsp;&nbsp; &nbsp; begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; Result:= petOwner.Pets;</div><div class="code_line">&nbsp;&nbsp; &nbsp; end);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; Writeln(&#39;Using SelectMany:&#39;);</div><div class="code_line">&nbsp;&nbsp; for var Pet in Query1 do</div><div class="code_line">&nbsp;&nbsp; &nbsp; Writeln(Pet);</div><div class="code_line">&nbsp;&nbsp; Writeln;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; // This code shows how to use Select</div><div class="code_line">&nbsp;&nbsp; // instead of SelectMany.</div><div class="code_line">&nbsp;&nbsp; var Query2:= PetOwners.Select&#60;IEnumerable&#60;string&#62;&#62;(</div><div class="code_line">&nbsp;&nbsp; &nbsp; function (petOwner: TPetOwner): IEnumerable&#60;string&#62;</div><div class="code_line">&nbsp;&nbsp; &nbsp; begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; Result:= petOwner.Pets;</div><div class="code_line">&nbsp;&nbsp; &nbsp; end);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; Writeln(&#39;Using Select:&#39;);</div><div class="code_line">&nbsp;&nbsp; for var petList in Query2 do</div><div class="code_line">&nbsp;&nbsp; &nbsp; for var pet in petList do</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; Writeln(pet);</div><div class="code_line">&nbsp;&nbsp; Writeln; &nbsp;</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">end.</div></ol></div></div></div></div><br>
Засчет чего код упростился? <br>
Все вызовы Select|SelectMany идут через PetOwners, он был вынесен из списка параметров, в отличие от TEnumerable, засчет чего теперь не надо передавать тип TPetOwner в качестве параметров шаблона. Да и в модуле Spring.Collections.Enumerable есть реализации для всех методов IEnumerable&lt;T&gt;, тогда как TEnumerable реализует например не все методы Select|SelectMany и мне пришлось самому писать их, хотя на самом деле добавить их не составило труда :D<br>
Сравните вызов SelectMany из первого поста:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">var Query1 := TEnumerable.SelectMany&#60;TPetOwner, string&#62;(</div><div class="code_line">&nbsp;&nbsp;PetOwners, function (petOwner: TPetOwner): IEnumerable&#60;string&#62;</div><div class="code_line">&nbsp;&nbsp; &nbsp; begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; Result:= petOwner.Pets;</div><div class="code_line">&nbsp;&nbsp; &nbsp; end);</div></ol></div></div></div></div><br>
и новый <br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">var Query1 := PetOwners.SelectMany&#60;string&#62;(</div><div class="code_line">&nbsp;&nbsp; &nbsp; function (petOwner: TPetOwner): IEnumerable&#60;string&#62;</div><div class="code_line">&nbsp;&nbsp; &nbsp; begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; Result:= petOwner.Pets;</div><div class="code_line">&nbsp;&nbsp; &nbsp; end);</div></ol></div></div></div></div><br>
лучше не так ли?]]></description>
        <author>Cfon</author>
        <category>Delphi: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3794875</guid>
        <pubDate>Fri, 05 Apr 2019 17:46:00 +0000</pubDate>
        <title>Spring4D</title>
        <link>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3794875</link>
        <description><![CDATA[Cfon: ОК, немного базовых операций со Spring.Collections<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">uses</div><div class="code_line">&nbsp;&nbsp;System.SysUtils,</div><div class="code_line">&nbsp;&nbsp;Spring.Collections;</div><div class="code_line">&nbsp;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;// диапазон целых чисел от 1 до 1000</div><div class="code_line">&nbsp;&nbsp;var numbers: IEnumerable&#60;integer&#62; := TEnumerable.Range(1, 1000);</div><div class="code_line">&nbsp;&nbsp;// перемешиваем</div><div class="code_line">&nbsp;&nbsp;var shuffled:= numbers.Shuffled;</div><div class="code_line">&nbsp;&nbsp;// отфильтровыем четные числа</div><div class="code_line">&nbsp;&nbsp;var evens:= shuffled.Where(function (const i: integer): boolean</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Result:= not Odd(i);</div><div class="code_line">&nbsp;&nbsp; &nbsp;end);</div><div class="code_line">&nbsp;&nbsp;// берем первые десять чисел</div><div class="code_line">&nbsp;&nbsp;var firstTen:= evens.Take(10);</div><div class="code_line">&nbsp;&nbsp;// реверсируем</div><div class="code_line">&nbsp;&nbsp;var reversed:= firstTen.Reversed;</div><div class="code_line">&nbsp;&nbsp;// извлекаем корень</div><div class="code_line">&nbsp;&nbsp;var sqrts:= TEnumerable.Select&#60;integer, extended&#62;(reversed,</div><div class="code_line">&nbsp;&nbsp; &nbsp;function (i: integer): extended</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Result:= sqrt(i);</div><div class="code_line">&nbsp;&nbsp; &nbsp;end);</div><div class="code_line">&nbsp;&nbsp;// выводим на консоль результат</div><div class="code_line">&nbsp;&nbsp;sqrts.ForEach(procedure (const x: extended)</div><div class="code_line">&nbsp;&nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Writeln(Format(&#39;Square root: %6.2f&#39;, [x]));</div><div class="code_line">&nbsp;&nbsp; &nbsp;end);</div><div class="code_line">end.</div></ol></div></div></div></div>]]></description>
        <author>Cfon</author>
        <category>Delphi: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3794873</guid>
        <pubDate>Fri, 05 Apr 2019 17:41:46 +0000</pubDate>
        <title>Spring4D</title>
        <link>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3794873</link>
        <description><![CDATA[Cfon: <div class='tag-quote'><a class='tag-quote-link' href='https://forum.sources.ru/index.php?showtopic=414484&view=findpost&p=3794848'><span class='tag-quote-prefix'>Цитата</span></a> <span class='tag-quote__quote-info'>Fr0sT &#064; <time class="tag-quote__quoted-time" datetime="2019-04-05T13:10:45+00:00">05.04.19, 13:10</time></span><div class='quote '>Ты Linq что ли ваяешь?</div></div><br>
Изучаю Spring4D <br>
<div class='tag-quote'><a class='tag-quote-link' href='https://forum.sources.ru/index.php?showtopic=414484&view=findpost&p=3794870'><span class='tag-quote-prefix'>Цитата</span></a> <span class='tag-quote__quote-info'>jack128 &#064; <time class="tag-quote__quoted-time" datetime="2019-04-05T17:15:56+00:00">05.04.19, 17:15</time></span><div class='quote '><div class='tag-quote'><a class='tag-quote-link' href='https://forum.sources.ru/index.php?showtopic=414484&view=findpost&p=3794827'><span class='tag-quote-prefix'>Цитата</span></a> <span class='tag-quote__quote-info'>Cfon &#064; <time class="tag-quote__quoted-time" datetime="2019-04-05T10:12:59+00:00">05.04.19, 10:12</time></span><div class='quote '>или шарп тоже стал динамическим?</div></div><br>
нет, просто в шарпе работает вывод типов в том числе и для generic параметров и для много чего.</div></div><br>
Хорошо б в делфи тоже сделать. А то капец как муторно исправлять ошибки ввода типов в двух а то и более местах  :D]]></description>
        <author>Cfon</author>
        <category>Delphi: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3794870</guid>
        <pubDate>Fri, 05 Apr 2019 17:15:56 +0000</pubDate>
        <title>Spring4D</title>
        <link>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3794870</link>
        <description><![CDATA[jack128: <div class='tag-quote'><a class='tag-quote-link' href='https://forum.sources.ru/index.php?showtopic=414484&view=findpost&p=3794827'><span class='tag-quote-prefix'>Цитата</span></a> <span class='tag-quote__quote-info'>Cfon &#064; <time class="tag-quote__quoted-time" datetime="2019-04-05T10:12:59+00:00">05.04.19, 10:12</time></span><div class='quote '>или шарп тоже стал динамическим?</div></div><br>
нет, просто в шарпе работает вывод типов в том числе и для generic параметров и для много чего.]]></description>
        <author>jack128</author>
        <category>Delphi: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3794848</guid>
        <pubDate>Fri, 05 Apr 2019 13:10:45 +0000</pubDate>
        <title>Spring4D</title>
        <link>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3794848</link>
        <description><![CDATA[Fr0sT: Ты Linq что ли ваяешь?]]></description>
        <author>Fr0sT</author>
        <category>Delphi: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3794827</guid>
        <pubDate>Fri, 05 Apr 2019 10:12:59 +0000</pubDate>
        <title>Spring4D</title>
        <link>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3794827</link>
        <description><![CDATA[Cfon: А теперь дельфийски хард-кор&#33;  :D <br>
Очень сложный пример SelectMany тока для хард-кодеров&#33; :wizard:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">uses</div><div class="code_line">&nbsp;&nbsp;System.SysUtils,</div><div class="code_line">&nbsp;&nbsp;Spring.Collections, </div><div class="code_line">&nbsp;&nbsp;Spring.Collections.Extensions;</div><div class="code_line">&nbsp;</div><div class="code_line">type</div><div class="code_line">&nbsp;&nbsp;TEnumerableHelper = class helper for TEnumerable</div><div class="code_line">&nbsp;&nbsp; &nbsp;....</div><div class="code_line">&nbsp;&nbsp; &nbsp;class function SelectMany&#60;T, C, R&#62;(const source: IEnumerable&#60;T&#62;;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;const collectionSelector: TFunc&#60;T, IEnumerable&#60;C&#62;&#62;;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;const resultSelector: TFunc&#60;T, C, R&#62;): IEnumerable&#60;R&#62;; overload; static;</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;TPetOwner = record</div><div class="code_line">&nbsp;&nbsp; &nbsp;Name: string;</div><div class="code_line">&nbsp;&nbsp; &nbsp;Pets: IList&#60;string&#62;; &nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;constructor Create(AName: string; APets: IList&#60;string&#62;);</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;TOwnerAndPet = record</div><div class="code_line">&nbsp;&nbsp; &nbsp;owner: TPetOwner;</div><div class="code_line">&nbsp;&nbsp; &nbsp;petName: string;</div><div class="code_line">&nbsp;&nbsp; &nbsp;constructor Create(AOwner: TPetOwner; APetName: string);</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;TOwnerNameAndPetName = record</div><div class="code_line">&nbsp;&nbsp; &nbsp;ownerName: string;</div><div class="code_line">&nbsp;&nbsp; &nbsp;petName: string;</div><div class="code_line">&nbsp;&nbsp; &nbsp;constructor Create(AOwnerName: string; APetName: string);</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;</div><div class="code_line">{ TEnumerableHelper }</div><div class="code_line">&nbsp;</div><div class="code_line">class function TEnumerableHelper.SelectMany&#60;T, C, R&#62;(const source: IEnumerable&#60;T&#62;;</div><div class="code_line">&nbsp;&nbsp;const collectionSelector: TFunc&#60;T, IEnumerable&#60;C&#62;&#62;;</div><div class="code_line">&nbsp;&nbsp;const resultSelector: TFunc&#60;T, C, R&#62;): IEnumerable&#60;R&#62;;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;Result:= TSelectManyIterator&#60;T, C, R&#62;.Create(source,</div><div class="code_line">&nbsp;&nbsp; &nbsp;collectionSelector,</div><div class="code_line">&nbsp;&nbsp; &nbsp;resultSelector);</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">{ TPetOwner }</div><div class="code_line">&nbsp;</div><div class="code_line">constructor TPetOwner.Create(AName: string; APets: IList&#60;string&#62;);</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;Name:= AName;</div><div class="code_line">&nbsp;&nbsp;Pets:= APets;</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">{ TOwnerAndPet }</div><div class="code_line">&nbsp;</div><div class="code_line">constructor TOwnerAndPet.Create(AOwner: TPetOwner; APetName: string);</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;owner:= AOwner;</div><div class="code_line">&nbsp;&nbsp;petName:= APetName;</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">{ TOwnerNameAndPetName }</div><div class="code_line">&nbsp;</div><div class="code_line">constructor TOwnerNameAndPetName.Create(AOwnerName, APetName: string);</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;ownerName:= AOwnerName;</div><div class="code_line">&nbsp;&nbsp;petName:= APetName;</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;var PetOwners := TCollections.CreateList&#60;TPetOwner&#62;([</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;TPetOwner.Create(&#39;Higa&#39;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;TCollections.CreateList&#60;string&#62;([&#39;Scruffy&#39;, &#39;Sam&#39;])),</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;TPetOwner.Create(&#39;Ashkenazi&#39;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;TCollections.CreateList&#60;string&#62;([&#39;Walker&#39;, &#39;Sugar&#39;])),</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;TPetOwner.Create(&#39;Price&#39;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;TCollections.CreateList&#60;string&#62;([&#39;Scratches&#39;, &#39;Diesel&#39;])),</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;TPetOwner.Create(&#39;Hines&#39;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;TCollections.CreateList&#60;string&#62;([&#39;Dusty&#39;]))</div><div class="code_line">&nbsp;&nbsp; &nbsp;]);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// Project the pet owner&#39;s name and the pet&#39;s name.</div><div class="code_line">&nbsp;&nbsp;var Query := TEnumerable</div><div class="code_line">&nbsp;&nbsp; &nbsp;.SelectMany&#60;TPetOwner, string, TOwnerAndPet&#62;(PetOwners,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;function (petOwner: TPetOwner): IEnumerable&#60;string&#62;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Result:= petOwner.Pets;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;end,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;function (owner: TPetOwner; petName: string): TOwnerAndPet</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Result:= TOwnerAndPet.Create(owner, petName);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;end)</div><div class="code_line">&nbsp;&nbsp; &nbsp;.Where(function (const ownerAndPet: TOwnerAndPet): Boolean</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Result:= ownerAndPet.petName.StartsWith(&#39;S&#39;);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;end);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;var Query2:= TEnumerable.Select&#60;TOwnerAndPet, TOwnerNameAndPetName&#62;(Query,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;function (ownerAndPet: TOwnerAndPet): TOwnerNameAndPetName</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Result:= TOwnerNameAndPetName.Create(</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ownerAndPet.owner.Name, ownerAndPet.petName);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;end);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// Print the results.</div><div class="code_line">&nbsp;&nbsp;for var obj in Query2 do</div><div class="code_line">&nbsp;&nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp;Writeln(Format(&#39;{Owner=%s, Pet=%s}&#39;, [obj.ownerName, obj.petName]));</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">// This code produces the following output:</div><div class="code_line">//</div><div class="code_line">// {Owner=Higa, Pet=Scruffy}</div><div class="code_line">// {Owner=Higa, Pet=Sam}</div><div class="code_line">// {Owner=Ashkenazi, Pet=Sugar}</div><div class="code_line">// {Owner=Price, Pet=Scratches}</div><div class="code_line">&nbsp;</div><div class="code_line">end.</div></ol></div></div></div></div><br>
Переводя шарповый код на дельфи столкнулся с необходимостью определять запись на каждый чих, это очень утомляет :D <br>
Сравните код Делфи и Шарп:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">var query = petOwners</div><div class="code_line">&nbsp;&nbsp; &nbsp;.SelectMany(petOwner =&#62; petOwner.Pets, (petOwner, petName) =&#62; new { petOwner, petName })</div><div class="code_line">&nbsp;&nbsp; &nbsp;.Where(ownerAndPet =&#62; ownerAndPet.petName.StartsWith(&quot;S&quot;))</div><div class="code_line">&nbsp;&nbsp; &nbsp;.Select(ownerAndPet =&#62;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;new</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Owner = ownerAndPet.petOwner.Name,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Pet = ownerAndPet.petName</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}</div><div class="code_line">&nbsp;&nbsp; &nbsp;);</div></ol></div></div></div></div><br>
Разница большая. на шарпе выглядит почти как если кодить на JS. <br>
Мой вердикт пока Делфи не сократит синтаксис до варика C# писать в функциональном стиле в нем это жесть&#33;  :D<br>
ПС. Надо хотя бы ввести вывод типов дженерик функций, чтобы писать типо:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">var Query2:= TEnumerable.Select(Query,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;function (ownerAndPet: TOwnerAndPet): TOwnerNameAndPetName</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Result:= TOwnerNameAndPetName.Create(</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ownerAndPet.owner.Name, ownerAndPet.petName);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;end);</div></ol></div></div></div></div><br>
и то короче, понимаю что убрать типизацию параметров нельзя это ж Делфи, а не JS хотя в шарпе ж в анонимках убрали както :D<br>
или шарп тоже стал динамическим?]]></description>
        <author>Cfon</author>
        <category>Delphi: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3794770</guid>
        <pubDate>Thu, 04 Apr 2019 18:54:55 +0000</pubDate>
        <title>Spring4D</title>
        <link>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3794770</link>
        <description><![CDATA[Cfon: Более сложный пример с SelectMany, поскольку пришлось расширять класс TEnumerable и в SelectMany идет дополнительный вызов Select, так что не сразу понять как все это работает. <br>
Атеншен&#33; Хитросплетения анонимок могет взорвать моск&#33; :ph34r: <br>
Думаю если сделать три вложения анонимок, то можно растаца с разумом  :lool: <br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">uses</div><div class="code_line">&nbsp;&nbsp;System.SysUtils</div><div class="code_line">, Spring.Collections</div><div class="code_line">, Spring.Collections.Extensions</div><div class="code_line">;</div><div class="code_line">&nbsp;</div><div class="code_line">type</div><div class="code_line">&nbsp;&nbsp;TPetOwner = class</div><div class="code_line">&nbsp;&nbsp; &nbsp;Name: string;</div><div class="code_line">&nbsp;&nbsp; &nbsp;Pets: IList&#60;string&#62;;</div><div class="code_line">&nbsp;&nbsp; &nbsp;constructor Create(AName: string; APets: IList&#60;string&#62;);</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;TEnumerableHelper = class helper for TEnumerable</div><div class="code_line">&nbsp;&nbsp; &nbsp;class function SelectMany&#60;T, TResult&#62;(const source: IEnumerable&#60;T&#62;;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;const selector: TFunc&#60;T, Integer, IEnumerable&#60;TResult&#62;&#62;): IEnumerable&#60;TResult&#62;; overload; static;</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;</div><div class="code_line">{ TPetsOwner }</div><div class="code_line">&nbsp;</div><div class="code_line">constructor TPetOwner.Create(AName: string; APets: IList&#60;string&#62;);</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;Name:= AName; Pets:= APets;</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">{ TEnumerableHelper }</div><div class="code_line">&nbsp;</div><div class="code_line">class function TEnumerableHelper.SelectMany&#60;T, TResult&#62;(const source: IEnumerable&#60;T&#62;;</div><div class="code_line">&nbsp;&nbsp;const selector: TFunc&#60;T, Integer, IEnumerable&#60;TResult&#62;&#62;): IEnumerable&#60;TResult&#62;;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp; Result := TSelectManyIndexIterator&#60;T, TResult&#62;.Create(source, selector);</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;var PetOwners := TCollections.CreateList&#60;TPetOwner&#62;([</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;TPetOwner.Create(&#39;Higa, Sidney&#39;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;TCollections.CreateList&#60;string&#62;([&#39;Scruffy&#39;, &#39;Sam&#39;])),</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;TPetOwner.Create(&#39;Ashkenazi, Ronen&#39;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;TCollections.CreateList&#60;string&#62;([&#39;Walker&#39;, &#39;Sugar&#39;])),</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;TPetOwner.Create(&#39;Price, Vernette&#39;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;TCollections.CreateList&#60;string&#62;([&#39;Scratches&#39;, &#39;Diesel&#39;])),</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;TPetOwner.Create(&#39;Hines, Patrick&#39;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;TCollections.CreateList&#60;string&#62;([&#39;Dusty&#39;]))</div><div class="code_line">&nbsp;&nbsp; &nbsp;]);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// Query using SelectMany with Index.</div><div class="code_line">&nbsp;&nbsp;var Query := TEnumerable.SelectMany&#60;TPetOwner, string&#62;(PetOwners,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;function (petOwner: TPetOwner; Index: integer): IEnumerable&#60;string&#62;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Result:= TEnumerable.Select&#60;string, string&#62;(petOwner.Pets,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;function (pet: string): string</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Result:= Index.ToString + pet;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;end);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;end);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;Writeln(&#39;Using SelectMany with Index:&#39;);</div><div class="code_line">&nbsp;&nbsp;for var pet in Query do</div><div class="code_line">&nbsp;&nbsp; &nbsp;Writeln(pet);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;Readln;</div><div class="code_line">end.</div></ol></div></div></div></div>]]></description>
        <author>Cfon</author>
        <category>Delphi: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3794538</guid>
        <pubDate>Tue, 02 Apr 2019 19:14:06 +0000</pubDate>
        <title>Spring4D</title>
        <link>https://forum.sources.ru/index.php?showtopic=414484&amp;view=findpost&amp;p=3794538</link>
        <description><![CDATA[Cfon: <strong class='tag-b'>Spring4D</strong> IEnumerable&lt;T&gt; in action :D <br>
Использование методов TEnumerable. <br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">uses</div><div class="code_line">&nbsp;&nbsp;Spring.Collections;</div><div class="code_line">&nbsp;</div><div class="code_line">type</div><div class="code_line">&nbsp;&nbsp;TPetOwner = class</div><div class="code_line">&nbsp;&nbsp; &nbsp;Name: string;</div><div class="code_line">&nbsp;&nbsp; &nbsp;Pets: IList&#60;string&#62;;</div><div class="code_line">&nbsp;&nbsp; &nbsp;constructor Create(AName: string; APets: IList&#60;string&#62;);</div><div class="code_line">&nbsp;&nbsp;end;</div><div class="code_line">&nbsp;</div><div class="code_line">{ TPetsOwner }</div><div class="code_line">&nbsp;</div><div class="code_line">constructor TPetOwner.Create(AName: string; APets: IList&#60;string&#62;);</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;Name:= AName; Pets:= APets;</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp;var PetOwners := TCollections.CreateList&#60;TPetOwner&#62;([</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;TPetOwner.Create(&#39;Higa, Sidney&#39;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;TCollections.CreateList&#60;string&#62;([&#39;Scruffy&#39;, &#39;Sam&#39;])),</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;TPetOwner.Create(&#39;Ashkenazi, Ronen&#39;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;TCollections.CreateList&#60;string&#62;([&#39;Walker&#39;, &#39;Sugar&#39;])),</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;TPetOwner.Create(&#39;Price, Vernette&#39;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;TCollections.CreateList&#60;string&#62;([&#39;Scratches&#39;, &#39;Diesel&#39;]))</div><div class="code_line">&nbsp;&nbsp; &nbsp;]);</div><div class="code_line">&nbsp;&nbsp;// Query using SelectMany.</div><div class="code_line">&nbsp;&nbsp;var Query1 := TEnumerable.SelectMany&#60;TPetOwner, string&#62;(</div><div class="code_line">&nbsp;&nbsp; &nbsp;PetOwners, function (petOwner: TPetOwner): IEnumerable&#60;string&#62;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Result:= petOwner.Pets;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;end);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;Writeln(&#39;Using SelectMany:&#39;);</div><div class="code_line">&nbsp;&nbsp;for var Pet in Query1 do</div><div class="code_line">&nbsp;&nbsp; &nbsp;Writeln(Pet);</div><div class="code_line">&nbsp;&nbsp;Writeln;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;// This code shows how to use Select</div><div class="code_line">&nbsp;&nbsp;// instead of SelectMany.</div><div class="code_line">&nbsp;&nbsp;var Query2:= TEnumerable.Select&#60;TPetOwner, IEnumerable&#60;string&#62;&#62;(</div><div class="code_line">&nbsp;&nbsp; &nbsp;PetOwners, function (petOwner: TPetOwner): IEnumerable&#60;string&#62;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Result:= petOwner.Pets;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;end);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;Writeln(&#39;Using Select:&#39;);</div><div class="code_line">&nbsp;&nbsp;for var petList in Query2 do</div><div class="code_line">&nbsp;&nbsp; &nbsp;for var pet in petList do</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Writeln(pet);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;Readln;</div><div class="code_line">end.</div></ol></div></div></div></div><br>
все примеры с сайта <a class='tag-url' href='https://docs.microsoft.com/en-us/dotnet/api/system.linq.enumerable?view=netframework-4.7.2' target='_blank'>https://docs.microsoft.com/en-us/dotnet/api...framework-4.7.2</a> <br>
Там на шарпе может кто не шарит, а спринг хоца юзат ну вот я вам и переведу :D <br>
<br>
To be continue...<br>
<br>
ПС. Delphi 10.3.1 Rio, Spring4D 1.2.2.<br>
Все примеры рабочие.]]></description>
        <author>Cfon</author>
        <category>Delphi: Общие вопросы</category>
      </item>
	
      </channel>
      </rss>
	