3

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

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

  TMyRecArray = array of TMyRec;

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

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

每个元素都有一个Color. 我的输出应按 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

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

4

1 回答 1

7

“分而治之。” 您可以将属性收集和应用着色与决策分开。

  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, Number, 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, Number, Item: integer): TColor;
  begin
    case Item of
       1: Result := clRed;
       2: Result := clYellow;
       3: Result := clGreen;
       else Result := clGray;
    end;
  end;
于 2013-11-12T13:29:08.940 回答