скопировать содержимое из списка1 в список2 по определенным критериям - PullRequest
3 голосов
/ 23 ноября 2011

если у меня есть два списка дженериков, определенных таким образом:

type
  pMyList = record
    a, b: integer;
    c: string; 
  end;
  TMyList = TList<pMyList>;

var
  list1, list2: TMyList;

существует некоторая функция копирования содержимого из списка (es: list1) в другой список (es: list2), только если какое-то поле соответствует условию? Например, я хочу скопировать в list2 из списка list1 все записи, где a такое же значение, как например 1. В результате в list2 у меня есть все записи list1, где a = 1, за исключением всех других записей, где a - это значение, отличное от 1. С уважением, я решил проблему следующим образом:

for iIndex := 0 to Pred(list1.Count) do
  if list1[iIndex].a = myvalue then list2.Add(list1[iIndex]);

но хотел узнать, есть ли что-то более специфичное для выполнения этой операции, например, с использованием какой-либо функции delphi. Еще раз большое спасибо.

Ответы [ 2 ]

4 голосов
/ 23 ноября 2011

К сожалению, поскольку в Delphi отсутствуют лямбда-выражения, использующие Collections, или общие списки из среды Spring могут сделать исходный код немного длиннее. Также некоторые люди не любят использовать анонимные методы, потому что их синтаксис очень громоздок. Но это вопрос вкуса imho.

С коллекциями ваш пример будет выглядеть так:

list2.AddAll(list1.Where(
  function(value: pMyList): Boolean
  begin
    Result := value.a = myvalue;
  end));

Имейте в виду, что обе упомянутые реализации универсальных списков реализуют интерфейсы, и большинство методов работают с ними. В приведенном выше примере это не имеет значения, потому что вы не передаете list1 напрямую. В противном случае он будет освобожден после.

С этим единственным примером преимущества их использования могут быть неясны, но когда вы выполняете много операций, фильтруете данные, помещаете их в другие списки и многое другое, это становится проще, и вам не нужно писать много дополнительных методов. сделать эти операции. Но, как я уже сказал, это дело вкуса, многим разработчикам Delphi не нравится этот синтаксис и способ написания кода.

0 голосов
/ 23 ноября 2011

Как насчет этого?

class procedure TCollectionUtils.CopyItems<T> (List1, List2 : TList <T>; Pred : TFunc <T, Boolean>);
var
 Item : T;
begin
for Item in List1 do
  if Pred (Item) then
    List2.Add (Item);
end;

Звонок будет выглядеть так:

TCollectionUtils.CopyItems <pMyList> (list1, list2,
  function (Item : pMyList) : Boolean
  begin
  Result := (pMyList.a = 1);
  end);

(здесь сейчас нет Delphi)

...