Delphi 如何从TList读取分组数据<&燃气轮机;在德尔菲

Delphi 如何从TList读取分组数据<&燃气轮机;在德尔菲,delphi,tlist,delphi-xe3,Delphi,Tlist,Delphi Xe3,在C#中,Linq将使这变得非常简单,但我对在Delphi中使用列表还不熟悉,我需要一些建议 我有一个对象列表,存储为TList,每个对象本质上都是一组数据,例如 1, 1, 2, 2, 2, 2, 3, 4, 4, 4 我希望创建一个新的t列表,其中列表中的项目分组如下: 1, 1 2, 2, 2, 2, 2 3 4, 4, 4 在Delphi XE3(初学者版)中,最有效的方法是什么?最简单的方法是一组循环。使用Delphi的DeHL或Spring框架可能会稍微缩短代码,但不会

在C#中,Linq将使这变得非常简单,但我对在Delphi中使用列表还不熟悉,我需要一些建议

我有一个对象列表,存储为
TList
,每个对象本质上都是一组数据,例如

1, 1, 2, 2, 2, 2, 3, 4, 4, 4 
我希望创建一个新的
t列表
,其中列表中的项目分组如下:

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

在Delphi XE3(初学者版)中,最有效的方法是什么?

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

关于使用条件查询通用TList实例给出了使用Spring框架中的集合的提示

使用
Integer
代替您的接口类型,但它应该很容易适应

下面是两种拆分方法,具体取决于您是希望每个列表从一个不断变化的值开始,还是仅针对不同的值(如David所说:长寿
TDictionary

我明白了区别,我把你的例子翻了一番:

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.
集成子列表的程序拆分列表; {$APPTYPE控制台} {$R*.res} 使用 System.SysUtils, 系统、泛型、集合; 类型 TIntegerList=TList; TIntegerListList=TList; TMain=类(ToObject) 私有的 类函数AddNewIntegerList(IntegerListList:TIntegerListList):TIntegerList; 类程序AddValues(AllInteger:TIntegerList); 类过程Fill_NewListForEachValueChange(常量AllIntegers:TIntegerList;常量IntegerListList:TIntegerList); 类过程Fill_newlistfordistinctValue(常量AllIntegers:TIntegerList;常量IntegerListList:TIntegerList); 类过程自由(const IntegerListList:TIntegerListList); 类过程打印(常量整数列表:TIntegerList);超载; 类过程打印(常量整数列表:TINTEGERLIST);超载; 公众的 类程序运行; 结束; 类函数TMain.AddNewIntegerList(IntegerListList:TIntegerListList):TIntegerList; 开始 结果:=TIntegerList.Create; IntegerListList.Add(结果); 结束; 类过程TMain.AddValues(AllIntegers:TIntegerList); 开始 // 1, 1, 2, 2, 2, 2, 3, 4, 4, 4 增加(1); 增加(1); 增加(2); 增加(2); 增加(2); 增加(2); 增加(3); 增加(4); 增加(4); 增加(4); 结束; 类过程TMain.Fill_NewListForEachValueChange(常量AllIntegers:TIntegerList;常量IntegerListList:TIntegerList); 变量 整数列表:TIntegerList; 值:整数; 开始 对于AllIntegers中的值 开始 如果(IntegerListList.Count=0)或(Value IntegerList.First),则 IntegerList:=AddNewIntegerList(IntegerList); 整数列表。添加(值); 结束; 结束; 类过程TMain.Fill_newlistfordistinctValue(常量AllIntegers:TIntegerList;常量IntegerListList: 色彩学家); 类型 TIntegerListDictionary=t词典; 变量 IntegerListDictionary:TIntegerListDictionary; 整数列表:TIntegerList; 值:整数; 开始 IntegerListDictionary:=TIntegerListDictionary.Create(); 对于AllIntegers中的值 开始 如果IntegerListDictionary.ContainsKey(值),则 整数列表:=整数列表字典[值] 其他的 开始 IntegerList:=AddNewIntegerList(IntegerList); Add(Value,IntegerList); 结束; 整数列表。添加(值); 结束; 结束; 类过程TMain.Free(const IntegerListList:TIntegerListList); 变量 整数列表:TIntegerList; 开始 对于IntegerListList中的IntegerList do 整数列表。自由; 整数列表。免费; 结束; 类过程TMain.Print(常量整数列表:TIntegerList); 变量 值:整数; 第一:布尔型; 开始 第一:=正确; 对于整数列表do中的值 开始 如果不是首先 写(','); 写入(值); 第一:=假; 结束; 书面语; 结束; 类过程TMain.Print(常量整数列表:tintegerlist); 变量 整数列表:TIntegerList; 开始 对于IntegerListList中的IntegerList do 打印(整数列表); 书面语; 结束; 类程序TMain.Run; 变量 联合情报员:情报员; 整数列表:TIntegerListList; 开始 AllIntegers:=TIntegerList.Create(); 尝试 AddValues(AllIntegers); 印刷(AllIntegers); IntegerListList:=TIntegerListList.Create(); 尝试 填写新列表ForEachValueChange(AllIntegers、IntegerListList); 打印(整数列表); 最后 自由(整数列表); 结束; AddValues(AllIntegers); 印刷(AllIntegers); IntegerListList:=TIntegerListList.Create(); 尝试 填写新列表ForEachValueChange(AllIntegers、IntegerListList); 打印(整数列表); 最后 自由(整数列表); 结束; 印刷(AllIntegers); IntegerListList:=TIntegerListList.Create(); 尝试 填写不同值的新列表(AllIntegers、IntegerListList); 打印(整数列表); 最后 自由(整数列表); 结束; 最后 AllIntegers.免费; 结束; 结束; 开始 尝试 TMain.Run(); 除了 关于E:Exception-do Writeln(E.ClassName,“:”,E.Message); 结束; 结束。
我会用字典收集这些组。没有比Delphi中的Linq更流畅的了。
TList的
TDictionary
的+1我认为一些算法的概要会有所帮助。仅仅说“使用一组循环”可能不够具体。我一回到有泛型的机器上就可以了。非常感谢你花时间写这个例子Jeroen,它帮助了我很多。从我最初的帖子开始,我就用TDictionary做了一个类似的函数(按照David的建议),但是你的例子用非常有用的额外内容对它进行了扩展。我有一些关于释放内存的问题,但我认为发布se更合适