我做了一个简化的演示(带有伪结构)来说明我需要的东西:
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;