delphi – 按阵列或列表中的GroupID对元素进行分组?

我做了一个简化的演示(带有伪结构)来说明我需要的东西:

type
  TMyRec = record
    GroupID: Integer;
    Color: TColor;
  end;

  TMyRecArray = array of TMyRec;

我的输入数组/列表元素由非零GroupID组成.它们始终按GroupID分组(但未排序且无法排序):

GroupID
-------
2 
2
2
1
1
3
3
etc...

每个元素都有一个颜色.我的输出应该按GroupID分组,看起来应该是这样的(每个组都是clRed / clGreen – 依次交替):

GroupID ; Color
-------   -----
2 ; clRed
2 ; clRed
2 ; clRed
1 ; clGreen
1 ; clGreen
3 ; clRed
3 ; clRed
etc...
9 ; clGreen    
7 ; clRed
7 ; clRed

我用的代码是:

procedure TForm1.Button1Click(Sender: TObject);
var
  R: TMyRecArray;
  I: Integer;
  S: string;
  OldId: Integer;
begin
  // populate some data
  SetLength(R,7);
  R[0].GroupID := 2;
  R[1].GroupID := 2;
  R[2].GroupID := 2;
  R[3].GroupID := 1;
  R[4].GroupID := 1;
  R[5].GroupID := 3;
  R[6].GroupID := 3;

  OldId := 0;
  for I := 0 to High(R) do
  begin
    if OldId <> R[I].GroupID then
    begin
      OldId := R[I].GroupID;
      R[I].Color := clRed;
    end
    else
    begin
      R[I].Color := clGreen;
    end;
  end;

  Memo1.Clear;
  for I := 0 to High(R) do
  begin
    ColorToIdent(R[I].Color,S);
    Memo1.Lines.Add(Format('%d ; %s',[R[I].GroupID,S]));
  end;
end;

结果不正确:

2 ; clRed
2 ; clGreen
2 ; clGreen
1 ; clRed
1 ; clGreen
3 ; clRed
3 ; clGreen

我错过了什么?我知道解决方案很简单,但我无法理解它.
限制:我只能迭代一次;我无法提前阅读/以前的记录.

解决方法

“分而治之.”您可以从决策中分离属性的收集和应用着色.

OldId := 0; GroupNo := 0;
  for I := Low(R) to High(R) do
  begin
    if (OldId <> R[I].GroupId) or (GroupNo = 0) then
    begin
      OldId := R[I].GroupId;
      Inc(GroupNo);
      ItemNo := 0;
    end;
    Inc(ItemNo); 

    R[I].Color := GroupColor(OldId,GroupNo,ItemNo);
  end;

然后,您可以专注于选择本身,而不会满足于实际着色,数据迭代等细节.这也可以让您更灵活地实际需要什么. GroupColor甚至可以是变量,根据设置实现不同的突出显示模式.

你想要一组又一组的交替颜色吗?

function GroupColor(const Id,Number,Item: integer): TColor;
  begin
    if Odd(Number) 
       then Result := clRed
       else Result := clGreen
  end;

或者你想不同的团体有不同的颜色?

function GroupColor(const Id,Item: integer): TColor;
  begin
    case Id of
       1: Result := clRed;
       2: Result := clYellow;
       3: Result := clBlue;
       4: Result := clGreen;
       else Result := clWhite;
    end;
  end;

或者你想强调每个团队的领导者,领导者?

function GroupColor(const Id,Item: integer): TColor;
  begin
    case Item of
       1: Result := clRed;
       2: Result := clYellow;
       3: Result := clGreen;
       else Result := clGray;
    end;
  end;

相关文章

 从网上看到《Delphi API HOOK完全说明》这篇文章,基本上都...
  从网上看到《Delphi API HOOK完全说明》这篇文章,基本上...
ffmpeg 是一套强大的开源的多媒体库 一般都是用 c/c+&#x...
32位CPU所含有的寄存器有:4个数据寄存器(EAX、EBX、ECX和ED...
1 mov dst, src dst是目的操作数,src是源操作数,指令实现的...