На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! ПРАВИЛА РАЗДЕЛА · FAQ раздела Delphi · Книги по Delphi
Пожалуйста, выделяйте текст программы тегом [сode=pas] ... [/сode]. Для этого используйте кнопку [code=pas] в форме ответа или комбобокс, если нужно вставить код на языке, отличном от Дельфи/Паскаля.
Следующие вопросы задаются очень часто, подробно разобраны в FAQ и, поэтому, будут безжалостно удаляться:
1. Преобразовать переменную типа String в тип PChar (PAnsiChar)
2. Как "свернуть" программу в трей.
3. Как "скрыться" от Ctrl + Alt + Del (заблокировать их и т.п.)
4. Как прочитать список файлов, поддиректорий в директории?
5. Как запустить программу/файл?
... (продолжение следует) ...

Вопросы, подробно описанные во встроенной справочной системе Delphi, не несут полезной тематической нагрузки, поэтому будут удаляться.
Запрещается создавать темы с просьбой выполнить какую-то работу за автора темы. Форум является средством общения и общего поиска решения. Вашу работу за Вас никто выполнять не будет.


Внимание
Попытки открытия обсуждений реализации вредоносного ПО, включая различные интерпретации спам-ботов, наказывается предупреждением на 30 дней.
Повторная попытка - 60 дней. Последующие попытки бан.
Мат в разделе - бан на три месяца...
Модераторы: jack128, D[u]fa, Shaggy, Rouse_
Страницы: (4) [1] 2 3 ... Последняя » все  ( Перейти к последнему сообщению )  
> Spring4D , Функциональное программирование в действии
    Spring4D IEnumerable<T> in action :D
    Использование методов TEnumerable.
    ExpandedWrap disabled
      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
    Там на шарпе может кто не шарит, а спринг хоца юзат ну вот я вам и переведу :D

    To be continue...

    ПС. Delphi 10.3.1 Rio, Spring4D 1.2.2.
    Все примеры рабочие.
    Сообщение отредактировано: Cfon -
      Более сложный пример с SelectMany, поскольку пришлось расширять класс TEnumerable и в SelectMany идет дополнительный вызов Select, так что не сразу понять как все это работает.
      Атеншен! Хитросплетения анонимок могет взорвать моск! :ph34r:
      Думаю если сделать три вложения анонимок, то можно растаца с разумом :lool:
      ExpandedWrap disabled
        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.
      Сообщение отредактировано: Cfon -
        А теперь дельфийски хард-кор! :D
        Очень сложный пример SelectMany тока для хард-кодеров! :wizard:
        ExpandedWrap disabled
          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.

        Переводя шарповый код на дельфи столкнулся с необходимостью определять запись на каждый чих, это очень утомляет :D
        Сравните код Делфи и Шарп:
        ExpandedWrap disabled
          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# писать в функциональном стиле в нем это жесть! :D
        ПС. Надо хотя бы ввести вывод типов дженерик функций, чтобы писать типо:
        ExpandedWrap disabled
          var Query2:= TEnumerable.Select(Query,
                function (ownerAndPet: TOwnerAndPet): TOwnerNameAndPetName
                begin
                  Result:= TOwnerNameAndPetName.Create(
                    ownerAndPet.owner.Name, ownerAndPet.petName);
                end);

        и то короче, понимаю что убрать типизацию параметров нельзя это ж Делфи, а не JS хотя в шарпе ж в анонимках убрали както :D
        или шарп тоже стал динамическим?
        Сообщение отредактировано: Cfon -
          Ты Linq что ли ваяешь?
            Цитата Cfon @
            или шарп тоже стал динамическим?

            нет, просто в шарпе работает вывод типов в том числе и для generic параметров и для много чего.
              Цитата Fr0sT @
              Ты Linq что ли ваяешь?

              Изучаю Spring4D
              Цитата jack128 @
              Цитата Cfon @
              или шарп тоже стал динамическим?

              нет, просто в шарпе работает вывод типов в том числе и для generic параметров и для много чего.

              Хорошо б в делфи тоже сделать. А то капец как муторно исправлять ошибки ввода типов в двух а то и более местах :D
              Сообщение отредактировано: Cfon -
                ОК, немного базовых операций со Spring.Collections
                ExpandedWrap disabled
                  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.
                  Упрощаем код заюзав модуль Spring.Collections.Enumerable:
                  ExpandedWrap disabled
                    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 и мне пришлось самому писать их, хотя на самом деле добавить их не составило труда :D
                  Сравните вызов SelectMany из первого поста:
                  ExpandedWrap disabled
                    var Query1 := TEnumerable.SelectMany<TPetOwner, string>(
                      PetOwners, function (petOwner: TPetOwner): IEnumerable<string>
                         begin
                           Result:= petOwner.Pets;
                         end);

                  и новый
                  ExpandedWrap disabled
                    var Query1 := PetOwners.SelectMany<string>(
                         function (petOwner: TPetOwner): IEnumerable<string>
                         begin
                           Result:= petOwner.Pets;
                         end);

                  лучше не так ли?
                  Сообщение отредактировано: Cfon -
                    Продолжаю упрощать :D
                    Попытался переложить пример из поста #3 на рельсы Enumerable, но получаю ошибку, причем хз откуда она вылазит, дебугер стопица на асм-коде, я там не шарю не стал мучать себя поисками :D
                    Да на самом деле я сделал еще не большое упрощение кода, удалил последний Select, и сразу возращал массив TOwnerNameAndPetName. Вот тогда и стала вызалить ошибка :D, если переносить один в один то все пучком! :wacko:
                    ExpandedWrap disabled
                      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, то все пучком :wall:
                    ExpandedWrap disabled
                      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
                    че она делает я хз :blink:
                    Я так понел что какие то траблы в работе со строками.

                    Опа а если сделать копию PetOwners, то пашет! :wall:
                    ExpandedWrap disabled
                      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)
                            ;
                    Сообщение отредактировано: Cfon -
                      Дело было в инлайн переменной obj в цикле вывода
                      ExpandedWrap disabled
                        .....
                          // Print the results.
                          for var obj in Query do
                          begin
                            Writeln(Format('{Owner=%s, Pet=%s}', [obj.ownerName, obj.petName]));
                          end;

                      переместил ее в раздел объявлений и все! :D
                      Гениально! :lool:
                      ExpandedWrap disabled
                        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 поддерживает и так как там нет инлайна я перенес их в раздел объявлений, ну и все вдруг заработало :D
                      Почему она вылазила тока при замене TOwnerAndPet на TOwnerNameAndPetName я хз, пока не интересно :D
                      Не стабильно пока работает инлайнинг переменных :whistle:
                      ПС. другие инлайны не влияли на ошибку.
                      Сообщение отредактировано: Cfon -
                        Немного подробностей о Spring.Collections:

                        ExpandedWrap disabled
                          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 где определен один элемент:
                        ExpandedWrap disabled
                          Enumerable = record

                        TCollections реализует статические методы создания различных структур данных, интерфейсы которых определны выше.
                        TEnumerable реализует стат. методы обработки этих данных.
                        Enumerable тоже что и TEnumerable, но тока больше :D

                        Теперь некоторые особености реализации моих примеров, например в коде из поста #9 я создаю PetOwners как Enumerable<TPetOwner>, почему?
                        Потому что так проще заюзать SelectMany, конечно Enumerable<TPetOwner> это не полноценая структура данных таких как TList и другие, но нам их функциональность была не нужена в прмерах, смотрите как это выглядит через TCollections.CreateList:
                        ExpandedWrap disabled
                          // список
                            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 запрос. Сравните
                        ExpandedWrap disabled
                           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);

                        Проще не так ли?
                        Ну а если понадобится функции например списка? Нет проблем братишка это изиж зерь сюда :D
                        ExpandedWrap disabled
                          var listPetOwners := PetOwners.ToList;

                        Все дальше работаем как со списком :D
                        - Хэ а где try finally Free чувачок ах? мемори лик не?
                        Не братэлу тут у нас интерфесное прогание без всяких Free!
                        - Как так?
                        А вот так компиль сам все контролит и когда надо делитит мусор :D
                        - Фигасе! Клево!
                        А то! Интерморда рулит! :lool:

                        Упс я чутка поспешил :D
                        Объекты что хранит Enumerable не удаляются ибо они созданы не через механизм интерфейса, поэтому да их надо ручками удалять например
                        ExpandedWrap disabled
                          for var ob in PetOwners do
                          begin
                            ob.Free;
                          end;

                        или чтобы савсем не видет циклы то так :D
                        ExpandedWrap disabled
                          PetOwners.ForEach(procedure (const obj: TPetOwner)
                            begin
                              obj.Free;
                            end);

                        Ну или юзать методы типа TCollections.CreateObjectList, они по умолчанию сами делитят свое содержимое.

                        А можно заюзать интерфес IPetOwner для TPetOwner например
                        ExpandedWrap disabled
                          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 и все вручную уже не надо удалять :D
                        Или юзать запись вместо класса их тоже не надо удалять :lool:

                        Да и еще одна особеность примеров любое присваивание переменной выполняется один раз! Зачем?
                        ну это принципы функционального программирования, данные считаются неизмеными воооот... :D
                        Вот и я для каждого нового состояния юзал отдельную перемнную.
                        Сообщение отредактировано: Cfon -
                          Давайте закрепим тему :D
                          - Вывести список имен владельцев
                          - Вывести список имен владельцев и количество домашних животных
                          Это простые запросы, но они позволят нам понять как работает Select.
                          Данные те же список TPetOwner:
                          ExpandedWrap disabled
                            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']))
                              ]);
                          Сообщение отредактировано: Cfon -
                            Цитата Cfon @
                            Дело было в инлайн переменной obj в цикле вывода
                            переместил ее в раздел объявлений и все! :D
                            Гениально! :lool:
                            ExpandedWrap disabled
                              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 юзать рекорд.
                            ExpandedWrap disabled
                              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 @
                            Давайте закрепим тему :D
                            - Вывести список имен владельцев
                            - Вывести список имен владельцев и количество домашних животных
                            Это простые запросы, но они позволят нам понять как работает Select.

                            Решение :D
                            ExpandedWrap disabled
                              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;
                            Сообщение отредактировано: Cfon -
                              Уфф чет я завис на селектах :D
                              пора продолжать итак пишем Aggregate это аналог Reduce из JS, на сайте С# указаном выше, даны три примера, я их все сразу переложил на делфи:
                              ExpandedWrap disabled
                                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.

                              Я также привел код на шарпе, сравнивайте.
                                Задание! :whistle:
                                Надо перенести на Delphi. Кто не понел это код JS :D
                                ExpandedWrap disabled
                                  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"]
                                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                0 пользователей:


                                Рейтинг@Mail.ru
                                [ Script execution time: 0,0647 ]   [ 17 queries used ]   [ Generated: 23.04.24, 21:12 GMT ]