Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[13.58.252.8] |
|
Страницы: (4) [1] 2 3 ... Последняя » все ( Перейти к последнему сообщению ) |
Сообщ.
#1
,
|
|
|
Spring4D IEnumerable<T> in action
Использование методов TEnumerable. uses Spring.Collections; type TPetOwner = class Name: string; Pets: IList<string>; constructor Create(AName: string; APets: IList<string>); end; { TPetsOwner } constructor TPetOwner.Create(AName: string; APets: IList<string>); begin Name:= AName; Pets:= APets; end; begin var PetOwners := TCollections.CreateList<TPetOwner>([ TPetOwner.Create('Higa, Sidney', TCollections.CreateList<string>(['Scruffy', 'Sam'])), TPetOwner.Create('Ashkenazi, Ronen', TCollections.CreateList<string>(['Walker', 'Sugar'])), TPetOwner.Create('Price, Vernette', TCollections.CreateList<string>(['Scratches', 'Diesel'])) ]); // Query using SelectMany. var Query1 := TEnumerable.SelectMany<TPetOwner, string>( PetOwners, function (petOwner: TPetOwner): IEnumerable<string> begin Result:= petOwner.Pets; end); Writeln('Using SelectMany:'); for var Pet in Query1 do Writeln(Pet); Writeln; // This code shows how to use Select // instead of SelectMany. var Query2:= TEnumerable.Select<TPetOwner, IEnumerable<string>>( PetOwners, function (petOwner: TPetOwner): IEnumerable<string> begin Result:= petOwner.Pets; end); Writeln('Using Select:'); for var petList in Query2 do for var pet in petList do Writeln(pet); Readln; end. все примеры с сайта https://docs.microsoft.com/en-us/dotnet/api...framework-4.7.2 Там на шарпе может кто не шарит, а спринг хоца юзат ну вот я вам и переведу To be continue... ПС. Delphi 10.3.1 Rio, Spring4D 1.2.2. Все примеры рабочие. |
Сообщ.
#2
,
|
|
|
Более сложный пример с SelectMany, поскольку пришлось расширять класс TEnumerable и в SelectMany идет дополнительный вызов Select, так что не сразу понять как все это работает.
Атеншен! Хитросплетения анонимок могет взорвать моск! Думаю если сделать три вложения анонимок, то можно растаца с разумом uses System.SysUtils , Spring.Collections , Spring.Collections.Extensions ; type TPetOwner = class Name: string; Pets: IList<string>; constructor Create(AName: string; APets: IList<string>); end; TEnumerableHelper = class helper for TEnumerable class function SelectMany<T, TResult>(const source: IEnumerable<T>; const selector: TFunc<T, Integer, IEnumerable<TResult>>): IEnumerable<TResult>; overload; static; end; { TPetsOwner } constructor TPetOwner.Create(AName: string; APets: IList<string>); begin Name:= AName; Pets:= APets; end; { TEnumerableHelper } class function TEnumerableHelper.SelectMany<T, TResult>(const source: IEnumerable<T>; const selector: TFunc<T, Integer, IEnumerable<TResult>>): IEnumerable<TResult>; begin Result := TSelectManyIndexIterator<T, TResult>.Create(source, selector); end; begin var PetOwners := TCollections.CreateList<TPetOwner>([ TPetOwner.Create('Higa, Sidney', TCollections.CreateList<string>(['Scruffy', 'Sam'])), TPetOwner.Create('Ashkenazi, Ronen', TCollections.CreateList<string>(['Walker', 'Sugar'])), TPetOwner.Create('Price, Vernette', TCollections.CreateList<string>(['Scratches', 'Diesel'])), TPetOwner.Create('Hines, Patrick', TCollections.CreateList<string>(['Dusty'])) ]); // Query using SelectMany with Index. var Query := TEnumerable.SelectMany<TPetOwner, string>(PetOwners, function (petOwner: TPetOwner; Index: integer): IEnumerable<string> begin Result:= TEnumerable.Select<string, string>(petOwner.Pets, function (pet: string): string begin Result:= Index.ToString + pet; end); end); Writeln('Using SelectMany with Index:'); for var pet in Query do Writeln(pet); Readln; end. |
Сообщ.
#3
,
|
|
|
А теперь дельфийски хард-кор!
Очень сложный пример SelectMany тока для хард-кодеров! uses System.SysUtils, Spring.Collections, Spring.Collections.Extensions; type TEnumerableHelper = class helper for TEnumerable .... class function SelectMany<T, C, R>(const source: IEnumerable<T>; const collectionSelector: TFunc<T, IEnumerable<C>>; const resultSelector: TFunc<T, C, R>): IEnumerable<R>; overload; static; end; TPetOwner = record Name: string; Pets: IList<string>; constructor Create(AName: string; APets: IList<string>); end; TOwnerAndPet = record owner: TPetOwner; petName: string; constructor Create(AOwner: TPetOwner; APetName: string); end; TOwnerNameAndPetName = record ownerName: string; petName: string; constructor Create(AOwnerName: string; APetName: string); end; { TEnumerableHelper } class function TEnumerableHelper.SelectMany<T, C, R>(const source: IEnumerable<T>; const collectionSelector: TFunc<T, IEnumerable<C>>; const resultSelector: TFunc<T, C, R>): IEnumerable<R>; begin Result:= TSelectManyIterator<T, C, R>.Create(source, collectionSelector, resultSelector); end; { TPetOwner } constructor TPetOwner.Create(AName: string; APets: IList<string>); begin Name:= AName; Pets:= APets; end; { TOwnerAndPet } constructor TOwnerAndPet.Create(AOwner: TPetOwner; APetName: string); begin owner:= AOwner; petName:= APetName; end; { TOwnerNameAndPetName } constructor TOwnerNameAndPetName.Create(AOwnerName, APetName: string); begin ownerName:= AOwnerName; petName:= APetName; end; begin var PetOwners := TCollections.CreateList<TPetOwner>([ TPetOwner.Create('Higa', TCollections.CreateList<string>(['Scruffy', 'Sam'])), TPetOwner.Create('Ashkenazi', TCollections.CreateList<string>(['Walker', 'Sugar'])), TPetOwner.Create('Price', TCollections.CreateList<string>(['Scratches', 'Diesel'])), TPetOwner.Create('Hines', TCollections.CreateList<string>(['Dusty'])) ]); // Project the pet owner's name and the pet's name. var Query := TEnumerable .SelectMany<TPetOwner, string, TOwnerAndPet>(PetOwners, function (petOwner: TPetOwner): IEnumerable<string> begin Result:= petOwner.Pets; end, function (owner: TPetOwner; petName: string): TOwnerAndPet begin Result:= TOwnerAndPet.Create(owner, petName); end) .Where(function (const ownerAndPet: TOwnerAndPet): Boolean begin Result:= ownerAndPet.petName.StartsWith('S'); end); var Query2:= TEnumerable.Select<TOwnerAndPet, TOwnerNameAndPetName>(Query, function (ownerAndPet: TOwnerAndPet): TOwnerNameAndPetName begin Result:= TOwnerNameAndPetName.Create( ownerAndPet.owner.Name, ownerAndPet.petName); end); // Print the results. for var obj in Query2 do begin Writeln(Format('{Owner=%s, Pet=%s}', [obj.ownerName, obj.petName])); end; end; // This code produces the following output: // // {Owner=Higa, Pet=Scruffy} // {Owner=Higa, Pet=Sam} // {Owner=Ashkenazi, Pet=Sugar} // {Owner=Price, Pet=Scratches} end. Переводя шарповый код на дельфи столкнулся с необходимостью определять запись на каждый чих, это очень утомляет Сравните код Делфи и Шарп: var query = petOwners .SelectMany(petOwner => petOwner.Pets, (petOwner, petName) => new { petOwner, petName }) .Where(ownerAndPet => ownerAndPet.petName.StartsWith("S")) .Select(ownerAndPet => new { Owner = ownerAndPet.petOwner.Name, Pet = ownerAndPet.petName } ); Разница большая. на шарпе выглядит почти как если кодить на JS. Мой вердикт пока Делфи не сократит синтаксис до варика C# писать в функциональном стиле в нем это жесть! ПС. Надо хотя бы ввести вывод типов дженерик функций, чтобы писать типо: var Query2:= TEnumerable.Select(Query, function (ownerAndPet: TOwnerAndPet): TOwnerNameAndPetName begin Result:= TOwnerNameAndPetName.Create( ownerAndPet.owner.Name, ownerAndPet.petName); end); и то короче, понимаю что убрать типизацию параметров нельзя это ж Делфи, а не JS хотя в шарпе ж в анонимках убрали както или шарп тоже стал динамическим? |
Сообщ.
#4
,
|
|
|
Ты Linq что ли ваяешь?
|
Сообщ.
#5
,
|
|
|
Цитата Cfon @ или шарп тоже стал динамическим? нет, просто в шарпе работает вывод типов в том числе и для generic параметров и для много чего. |
Сообщ.
#6
,
|
|
|
Цитата Fr0sT @ Ты Linq что ли ваяешь? Изучаю Spring4D Цитата jack128 @ Цитата Cfon @ или шарп тоже стал динамическим? нет, просто в шарпе работает вывод типов в том числе и для generic параметров и для много чего. Хорошо б в делфи тоже сделать. А то капец как муторно исправлять ошибки ввода типов в двух а то и более местах |
Сообщ.
#7
,
|
|
|
ОК, немного базовых операций со Spring.Collections
uses System.SysUtils, Spring.Collections; begin // диапазон целых чисел от 1 до 1000 var numbers: IEnumerable<integer> := TEnumerable.Range(1, 1000); // перемешиваем var shuffled:= numbers.Shuffled; // отфильтровыем четные числа var evens:= shuffled.Where(function (const i: integer): boolean begin Result:= not Odd(i); end); // берем первые десять чисел var firstTen:= evens.Take(10); // реверсируем var reversed:= firstTen.Reversed; // извлекаем корень var sqrts:= TEnumerable.Select<integer, extended>(reversed, function (i: integer): extended begin Result:= sqrt(i); end); // выводим на консоль результат sqrts.ForEach(procedure (const x: extended) begin Writeln(Format('Square root: %6.2f', [x])); end); end. |
Сообщ.
#8
,
|
|
|
Упрощаем код заюзав модуль Spring.Collections.Enumerable:
uses System.SysUtils, Spring.Collections, Spring.Collections.Enumerable; type TPetOwner = class Name: string; Pets: IList<string>; constructor Create(AName: string; APets: IList<string>); end; { TPetOwner } constructor TPetOwner.Create(AName: string; APets: IList<string>); begin Name:= AName; Pets:= APets; end; begin var PetOwners := Enumerable<TPetOwner>.Create([ TPetOwner.Create('Higa, Sidney', TCollections.CreateList<string>(['Scruffy', 'Sam'])), TPetOwner.Create('Ashkenazi, Ronen', TCollections.CreateList<string>(['Walker', 'Sugar'])), TPetOwner.Create('Price, Vernette', TCollections.CreateList<string>(['Scratches', 'Diesel'])) ]); // Query using SelectMany. var Query1 := PetOwners.SelectMany<string>( function (petOwner: TPetOwner): IEnumerable<string> begin Result:= petOwner.Pets; end); Writeln('Using SelectMany:'); for var Pet in Query1 do Writeln(Pet); Writeln; // This code shows how to use Select // instead of SelectMany. var Query2:= PetOwners.Select<IEnumerable<string>>( function (petOwner: TPetOwner): IEnumerable<string> begin Result:= petOwner.Pets; end); Writeln('Using Select:'); for var petList in Query2 do for var pet in petList do Writeln(pet); Writeln; end; end. Засчет чего код упростился? Все вызовы Select|SelectMany идут через PetOwners, он был вынесен из списка параметров, в отличие от TEnumerable, засчет чего теперь не надо передавать тип TPetOwner в качестве параметров шаблона. Да и в модуле Spring.Collections.Enumerable есть реализации для всех методов IEnumerable<T>, тогда как TEnumerable реализует например не все методы Select|SelectMany и мне пришлось самому писать их, хотя на самом деле добавить их не составило труда Сравните вызов SelectMany из первого поста: var Query1 := TEnumerable.SelectMany<TPetOwner, string>( PetOwners, function (petOwner: TPetOwner): IEnumerable<string> begin Result:= petOwner.Pets; end); и новый var Query1 := PetOwners.SelectMany<string>( function (petOwner: TPetOwner): IEnumerable<string> begin Result:= petOwner.Pets; end); лучше не так ли? |
Сообщ.
#9
,
|
|
|
Продолжаю упрощать
Попытался переложить пример из поста #3 на рельсы Enumerable, но получаю ошибку, причем хз откуда она вылазит, дебугер стопица на асм-коде, я там не шарю не стал мучать себя поисками Да на самом деле я сделал еще не большое упрощение кода, удалил последний Select, и сразу возращал массив TOwnerNameAndPetName. Вот тогда и стала вызалить ошибка , если переносить один в один то все пучком! uses System.SysUtils, Spring.Collections, Spring.Collections.Enumerable; type TOwnerNameAndPetName = record ownerName: string; petName: string; constructor Create(AOwnerName: string; APetName: string); end; { TOwnerNameAndPetName } constructor TOwnerNameAndPetName.Create(AOwnerName, APetName: string); begin ownerName:= AOwnerName; petName:= APetName; end; begin var PetOwners := Enumerable<TPetOwner>.Create([ TPetOwner.Create('Higa', TCollections.CreateList<string>(['Scruffy', 'Sam'])), TPetOwner.Create('Ashkenazi', TCollections.CreateList<string>(['Walker', 'Sugar'])), TPetOwner.Create('Price', TCollections.CreateList<string>(['Scratches', 'Diesel'])), TPetOwner.Create('Hines', TCollections.CreateList<string>(['Dusty'])) ]); var Query := PetOwners .SelectMany<string, TOwnerNameAndPetName>( function (owner: TPetOwner): IEnumerable<string> begin Result:= owner.Pets; end, function (owner: TPetOwner; petName: string): TOwnerNameAndPetName begin Result:= TOwnerNameAndPetName.Create(owner.Name, petName); end) .Where(function (const ownerAndPet: TOwnerNameAndPetName): Boolean begin Result:= ownerAndPet.petName.StartsWith('S'); end); // тут был Select и его удалил и теперь ошибка // Print the results. for var obj in Query do begin Writeln(Format('{Owner=%s, Pet=%s}', [obj.ownerName, obj.petName])); end; end. Забыл сказать что все компилица, ошибка рантайм. Если заменить запись TOwnerNameAndPetName на TOwnerAndPet, то все пучком var Query := PetOwners .SelectMany<string, TOwnerAndPet>( function (owner: TPetOwner): IEnumerable<string> begin Result:= owner.Pets; end, function (owner: TPetOwner; petName: string): TOwnerAndPet begin Result:= TOwnerAndPet.Create(owner, petName); end) .Where(function (const ownerAndPet: TOwnerAndPet): Boolean begin Result:= ownerAndPet.petName.StartsWith('S'); end); // Print the results. for var obj in Query do begin Writeln(Format('{Owner=%s, Pet=%s}', [obj.owner.Name, obj.petName])); end; Ошибка в функции System._UStrAsg на асма-строке: LOCK DEC [EDX-skew].StrRec.refCnt че она делает я хз Я так понел что какие то траблы в работе со строками. Опа а если сделать копию PetOwners, то пашет! var Query := Enumerable<TPetOwner>.Create(PetOwners.ToArray) .SelectMany<string, TOwnerNameAndPetName>( function (owner: TPetOwner): IEnumerable<string> begin Result:= owner.Pets; end, function (owner: TPetOwner; petName: string): TOwnerNameAndPetName begin Result:= TOwnerNameAndPetName.Create(owner.Name, petName); end) .Where(function (const ownerAndPet: TOwnerNameAndPetName): Boolean begin Result:= ownerAndPet.petName.StartsWith('S'); end) ; |
Сообщ.
#10
,
|
|
|
Дело было в инлайн переменной obj в цикле вывода
..... // Print the results. for var obj in Query do begin Writeln(Format('{Owner=%s, Pet=%s}', [obj.ownerName, obj.petName])); end; переместил ее в раздел объявлений и все! Гениально! var obj: TOwnerNameAndPetName; begin ... // Print the results. for obj in Query do begin Writeln(Format('{Owner=%s, Pet=%s}', [obj.ownerName, obj.petName])); end; end. Как я обнаружил это? Все просто я установил Delphi XE2 ну ту что еще Spring4D поддерживает и так как там нет инлайна я перенес их в раздел объявлений, ну и все вдруг заработало Почему она вылазила тока при замене TOwnerAndPet на TOwnerNameAndPetName я хз, пока не интересно Не стабильно пока работает инлайнинг переменных ПС. другие инлайны не влияли на ошибку. |
Сообщ.
#11
,
|
|
|
Немного подробностей о Spring.Collections:
IEnumerable<T> = interface(IEnumerable) ICollection<T> = interface(IEnumerable<T>) IList<T> = interface(ICollection<T>) ... IMap<TKey, TValue> = interface(ICollection<TPair<TKey, TValue>> IDictionary<TKey, TValue> = interface(IMap<TKey, TValue>) TCollections = class TEnumerable = class Отдельно стоит Spring.Collections.Enumerable где определен один элемент: Enumerable = record TCollections реализует статические методы создания различных структур данных, интерфейсы которых определны выше. TEnumerable реализует стат. методы обработки этих данных. Enumerable тоже что и TEnumerable, но тока больше Теперь некоторые особености реализации моих примеров, например в коде из поста #9 я создаю PetOwners как Enumerable<TPetOwner>, почему? Потому что так проще заюзать SelectMany, конечно Enumerable<TPetOwner> это не полноценая структура данных таких как TList и другие, но нам их функциональность была не нужена в прмерах, смотрите как это выглядит через TCollections.CreateList: // список var PetOwners := TCollections.CreateList<TPetOwner>([ TPetOwner.Create('Higa', TCollections.CreateList<string>(['Scruffy', 'Sam'])), TPetOwner.Create('Ashkenazi', TCollections.CreateList<string>(['Walker', 'Sugar'])), TPetOwner.Create('Price', TCollections.CreateList<string>(['Scratches', 'Diesel'])), TPetOwner.Create('Hines', TCollections.CreateList<string>(['Dusty'])) ]); // запрос var Query := Enumerable<TPetOwner>.Create(PetOwners.ToArray) //<-- создаем .SelectMany<string>(function(owner: TPetOwner): IEnumerable<string> begin Result:= owner.Pets; end); Один фиг пришлось создать Enumerable<TPetOwner>, чтобы выполнить SelectMany запрос. Сравните var PetOwners := Enumerable<TPetOwner>.Create([ TPetOwner.Create('Higa', TCollections.CreateList<string>(['Scruffy', 'Sam'])), TPetOwner.Create('Ashkenazi', TCollections.CreateList<string>(['Walker', 'Sugar'])), TPetOwner.Create('Price', TCollections.CreateList<string>(['Scratches', 'Diesel'])), TPetOwner.Create('Hines', TCollections.CreateList<string>(['Dusty'])) ]); var Query := PetOwners.SelectMany<string>( function (owner: TPetOwner): IEnumerable<string> begin Result:= owner.Pets; end); Проще не так ли? Ну а если понадобится функции например списка? Нет проблем братишка это изиж зерь сюда var listPetOwners := PetOwners.ToList; Все дальше работаем как со списком - Хэ а где try finally Free чувачок ах? мемори лик не? Не братэлу тут у нас интерфесное прогание без всяких Free! - Как так? А вот так компиль сам все контролит и когда надо делитит мусор - Фигасе! Клево! А то! Интерморда рулит! Упс я чутка поспешил Объекты что хранит Enumerable не удаляются ибо они созданы не через механизм интерфейса, поэтому да их надо ручками удалять например for var ob in PetOwners do begin ob.Free; end; или чтобы савсем не видет циклы то так PetOwners.ForEach(procedure (const obj: TPetOwner) begin obj.Free; end); Ну или юзать методы типа TCollections.CreateObjectList, они по умолчанию сами делитят свое содержимое. А можно заюзать интерфес IPetOwner для TPetOwner например type IPetOwner = interface function GetName: string; procedure SetName(AName: string); function GetPets: IList<string>; property Name: string read GetName write SetName; property Pets: IList<string> read GetPets; end; TPetOwner = class(TInterfacedObject, IPetOwner) private FName: string; FPets: IList<string>; function GetName: string; procedure SetName(AName: string); function GetPets: IList<string>; public constructor Create(AName: string; APets: IList<string>); property Name: string read GetName write SetName; property Pets: IList<string> read GetPets; end; Там по коду тоже надо заменить TPetOwner на IPetOwner и все вручную уже не надо удалять Или юзать запись вместо класса их тоже не надо удалять Да и еще одна особеность примеров любое присваивание переменной выполняется один раз! Зачем? ну это принципы функционального программирования, данные считаются неизмеными воооот... Вот и я для каждого нового состояния юзал отдельную перемнную. |
Сообщ.
#12
,
|
|
|
Давайте закрепим тему
- Вывести список имен владельцев - Вывести список имен владельцев и количество домашних животных Это простые запросы, но они позволят нам понять как работает Select. Данные те же список TPetOwner: PetOwners := TCollections.CreateList<TPetOwner>([ TPetOwner.Create('Higa', TCollections.CreateList<string>(['Scruffy', 'Sam'])), TPetOwner.Create('Ashkenazi', TCollections.CreateList<string>(['Walker', 'Sugar'])), TPetOwner.Create('Price', TCollections.CreateList<string>(['Scratches', 'Diesel'])), TPetOwner.Create('Hines', TCollections.CreateList<string>(['Dusty'])) ]); |
Сообщ.
#13
,
|
|
|
Цитата Cfon @ Дело было в инлайн переменной obj в цикле вывода переместил ее в раздел объявлений и все! Гениально! var obj: TOwnerNameAndPetName; begin ... // Print the results. for obj in Query do begin Writeln(Format('{Owner=%s, Pet=%s}', [obj.ownerName, obj.petName])); end; end. Обнаружил еще решения данного косяка: 1- указать тип переменной obj в цикле. 2- вместо класса TPetOwner юзать рекорд. type TPetOwner = record Name: string; Pets: IList<string>; constructor Create(AName: string; APets: IList<string>); end; ..... begin ..... // Print the results. for var obj: TOwnerNameAndPetName in Query do begin Writeln(Format('{Owner=%s, Pet=%s}', [obj.ownerName, obj.petName])); end; end Добавлено Цитата Cfon @ Давайте закрепим тему - Вывести список имен владельцев - Вывести список имен владельцев и количество домашних животных Это простые запросы, но они позволят нам понять как работает Select. Решение begin var PetOwners := Enumerable<TPetOwner>.Create([ TPetOwner.Create('Higa', TCollections.CreateList<string>(['Scruffy', 'Sam'])), TPetOwner.Create('Ashkenazi',TCollections.CreateList<string>(['Walker', 'Sugar'])), TPetOwner.Create('Price', TCollections.CreateList<string>(['Scratches', 'Diesel'])), TPetOwner.Create('Hines', TCollections.CreateList<string>(['Dusty'])) ]); var Query:= PetOwners.Select<string>( function (owner: TPetOwner): string begin Result:= owner.Name; end); var Query2:= PetOwners.Select<TOwnerNameAndPetCount>( function (owner: TPetOwner): TOwnerNameAndPetCount begin Result:= TOwnerNameAndPetCount.Create(owner.Name, owner.Pets.Count); end); end; |
Сообщ.
#14
,
|
|
|
Уфф чет я завис на селектах
пора продолжать итак пишем Aggregate это аналог Reduce из JS, на сайте С# указаном выше, даны три примера, я их все сразу переложил на делфи: uses System.SysUtils, Spring.Collections, Spring.Collections.Enumerable; procedure AggregateEx1; begin var ints := TArray<integer>.Create(4, 8, 8, 3, 9, 0, 7, 8, 2); // Count the even numbers in the array, using a seed value of 0. var numEven:= Enumerable<integer>.Create(ints).Aggregate<integer>(0, function(total, next: integer): integer begin Result:= total; if next mod 2 = 0 then Result:= total + 1; end); Writeln('The number of even integers is: ', numEven); end; {$REGION 'C# code'} // int[] ints = { 4, 8, 8, 3, 9, 0, 7, 8, 2 }; // // // Count the even numbers in the array, using a seed value of 0. // int numEven = ints.Aggregate(0, (total, next) => // next % 2 == 0 ? total + 1 : total); // // Console.WriteLine("The number of even integers is: {0}", numEven); {$ENDREGION} // This code produces the following output: // // The number of even integers is: 6 procedure AggregateEx2; begin var sentence := 'the quick brown fox jumps over the lazy dog'; // Split the string into individual. var words:= TCollections.CreateList<string>(sentence.Split([' '])); // Prepend each word to the beginning of the // new sentence to reverse the word order. var reversed:= words.Aggregate( function (workingSentence, next: string): string begin Result:= next + ' ' + workingSentence; end ); Writeln(reversed); end; {$REGION 'C# code'} // string sentence = "the quick brown fox jumps over the lazy dog"; // // // Split the string into individual words. // string[] words = sentence.Split(' '); // // // Prepend each word to the beginning of the // // new sentence to reverse the word order. // string reversed = words.Aggregate((workingSentence, next) => // next + " " + workingSentence); // // Console.WriteLine(reversed); {$ENDREGION} // This code produces the following output: // // dog lazy the over jumps fox brown quick the procedure AggregateEx3; begin var fruits:= TArray<string>.Create('apple', 'mango', 'orange', 'passionfruit', 'grape'); // Determine whether any string in the array is longer than "banana". var longestName:= Enumerable<string>.Create(fruits) .Aggregate<string, string>('banana', function (longest, next:string): string begin Result:= longest; if Length(next) > Length(longest) then Result:= next; end, // Return the final result as an upper case string. function (fruit: string): string begin Result:= fruit.ToUpper; end); Writeln('The fruit with the longest name is ', longestName); end; {$REGION 'C# code'} // string[] fruits = { "apple", "mango", "orange", "passionfruit", "grape" }; // // // Determine whether any string in the array is longer than "banana". // string longestName = // fruits.Aggregate("banana", // (longest, next) => // next.Length > longest.Length ? next : longest, // // Return the final result as an upper case string. // fruit => fruit.ToUpper()); // // Console.WriteLine( // "The fruit with the longest name is {0}.", // longestName); {$ENDREGION} // This code produces the following output: // // The fruit with the longest name is PASSIONFRUIT. begin AggregateEx1; AggregateEx2; AggregateEx3; end; end. Я также привел код на шарпе, сравнивайте. |
Сообщ.
#15
,
|
|
|
Задание!
Надо перенести на Delphi. Кто не понел это код JS const colors = ["red", "red", "green", "blue", "green"]; const distinctColors = colors.reduce( (distinct, color) => (distinct.indexOf(color) !== -1) ? distinct : [...distinct, color], []); console.log(distinctColors); // ["red", "green", "blue"] |