簡體   English   中英

如何從Delphi中的TList <>讀取分組數據

[英]How can read grouped data from a TList<> in Delphi

在C#中,Linq會讓這個變得非常容易,但我不熟悉在Delphi中使用Lists,我需要一些建議。

我有一個存儲為TList<IMyInterface>對象TList<IMyInterface> ,每個對象基本上是一個數據集合,例如

1, 1, 2, 2, 2, 2, 3, 4, 4, 4 

我希望創建一個新的TList<TList<IMyInterface>> ,其中列表中的項目分組如下:

1, 1 
2, 2, 2, 2, 2 
3 
4, 4, 4 

在Delphi XE3(入門版)中最有效的方法是什么?

最簡單的是一組循環。 使用Delphi的DeHL或Spring框架可能會縮短您的代碼,但不會太多。

關於使用條件查詢通用TList實例的這個問題給出了使用Spring框架中的集合的提示。

我的示例使用Integer代替您的接口類型,但它應該很容易適應。

下面是兩種拆分方法,具體取決於您是希望每個列表都以更改的值開始,還是僅針對不同的值(如David所說:萬歲TDictionary<Key, Value>

我看到了區別,我把你的例子加倍:

1, 1, 2, 2, 2, 2, 3, 4, 4, 4, 1, 1, 2, 2, 2, 2, 3, 4, 4, 4

第一個算法將返回以下內容:

1, 1
2, 2, 2, 2
3
4, 4, 4
1, 1
2, 2, 2, 2
3
4, 4, 4

第二個:

1, 1, 1, 1
2, 2, 2, 2, 2, 2, 2, 2
3, 3
4, 4, 4, 4, 4, 4

這是示例程序; 只有打印需要嵌套循環。

program SplitListOfIntegersIntoSublists;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils,
  System.Generics.Collections;

type
  TIntegerList = TList<Integer>;
  TIntegerListList = TList<TIntegerList>;
  TMain = class(TObject)
  private
    class function AddNewIntegerList(IntegerListList: TIntegerListList): TIntegerList;
    class procedure AddValues(AllIntegers: TIntegerList);
    class procedure Fill_NewListForEachValueChange(const AllIntegers: TIntegerList; const IntegerListList: TIntegerListList);
    class procedure Fill_NewListForDistinctValues(const AllIntegers: TIntegerList; const IntegerListList: TIntegerListList);
    class procedure Free(const IntegerListList: TIntegerListList);
    class procedure Print(const IntegerList: TIntegerList); overload;
    class procedure Print(const IntegerListList: TIntegerListList); overload;
  public
    class procedure Run;
  end;

class function TMain.AddNewIntegerList(IntegerListList: TIntegerListList): TIntegerList;
begin
  Result := TIntegerList.Create;
  IntegerListList.Add(Result);
end;

class procedure TMain.AddValues(AllIntegers: TIntegerList);
begin
// 1, 1, 2, 2, 2, 2, 3, 4, 4, 4
  AllIntegers.Add(1);
  AllIntegers.Add(1);
  AllIntegers.Add(2);
  AllIntegers.Add(2);
  AllIntegers.Add(2);
  AllIntegers.Add(2);
  AllIntegers.Add(3);
  AllIntegers.Add(4);
  AllIntegers.Add(4);
  AllIntegers.Add(4);
end;

class procedure TMain.Fill_NewListForEachValueChange(const AllIntegers: TIntegerList; const IntegerListList: TIntegerListList);
var
  IntegerList: TIntegerList;
  Value: Integer;
begin
  for Value in AllIntegers do
  begin
    if (IntegerListList.Count = 0) or (Value <> IntegerList.First) then
      IntegerList := AddNewIntegerList(IntegerListList);
    IntegerList.Add(Value);
  end;
end;

class procedure TMain.Fill_NewListForDistinctValues(const AllIntegers: TIntegerList; const IntegerListList:
    TIntegerListList);
type
  TIntegerListDictionary = TDictionary<Integer, TIntegerList>;
var
  IntegerListDictionary: TIntegerListDictionary;
  IntegerList: TIntegerList;
  Value: Integer;
begin
  IntegerListDictionary := TIntegerListDictionary.Create();
  for Value in AllIntegers do
  begin
    if IntegerListDictionary.ContainsKey(Value) then
      IntegerList := IntegerListDictionary[Value]
    else
    begin
      IntegerList := AddNewIntegerList(IntegerListList);
      IntegerListDictionary.Add(Value, IntegerList);
    end;
    IntegerList.Add(Value);
  end;
end;

class procedure TMain.Free(const IntegerListList: TIntegerListList);
var
  IntegerList: TIntegerList;
begin
  for IntegerList in IntegerListList do
    IntegerList.Free;
  IntegerListList.Free;
end;

class procedure TMain.Print(const IntegerList: TIntegerList);
var
  Value: Integer;
  First: Boolean;
begin
  First := True;
  for Value in IntegerList do
  begin
    if not First then
      Write(', ');
    Write(Value);
    First := False;
  end;
  Writeln;
end;

class procedure TMain.Print(const IntegerListList: TIntegerListList);
var
  IntegerList: TIntegerList;
begin
  for IntegerList in IntegerListList do
    Print(IntegerList);
  Writeln;
end;

class procedure TMain.Run;
var
  AllIntegers: TIntegerList;
  IntegerListList: TIntegerListList;
begin
  AllIntegers := TIntegerList.Create();
  try
    AddValues(AllIntegers);
    Print(AllIntegers);

    IntegerListList := TIntegerListList.Create();
    try
      Fill_NewListForEachValueChange(AllIntegers, IntegerListList);
      Print(IntegerListList);
    finally
      Free(IntegerListList);
    end;

    AddValues(AllIntegers);
    Print(AllIntegers);

    IntegerListList := TIntegerListList.Create();
    try
      Fill_NewListForEachValueChange(AllIntegers, IntegerListList);
      Print(IntegerListList);
    finally
      Free(IntegerListList);
    end;

    Print(AllIntegers);

    IntegerListList := TIntegerListList.Create();
    try
      Fill_NewListForDistinctValues(AllIntegers, IntegerListList);
      Print(IntegerListList);
    finally
      Free(IntegerListList);
    end;
  finally
    AllIntegers.Free;
  end;
end;

begin
  try
    TMain.Run();
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM