如何从TList读取分组数据<>在德尔福

时间:2012-10-02 01:23:16

标签: delphi tlist delphi-xe3

在C#中,Linq会让这个变得非常容易,但我不熟悉在Delphi中使用Lists,我需要一些建议。

我有一个存储为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(入门版)中执行此操作的最有效方法是什么?

1 个答案:

答案 0 :(得分:3)

最简单的是一组循环。使用Delphi的DeHL或Spring框架可能会缩短您的代码,但不会太多。

关于使用条件查询通用TList实例的

This question提供了使用Spring框架中的集合的提示。

My example使用Integer代替您的界面类型,但它应该很容易适应。

以下是两种拆分方法,具体取决于您是希望每个列表都以更改的值开始,还是仅针对不同的值(例如David说:long 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.