我做了一个简化的演示(带有伪结构)来说明我需要的东西:
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
我错过了什么?我知道解决方案很简单但我无法理解它。
限制:我只能迭代一次;我无法提前阅读/以前的记录。
答案 0 :(得分: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;