2

说我有一个组合框

apples
apples
pears
oranges
oranges

我想让它显示

apples
pears
oranges

我怎样才能做到这一点?

4

6 回答 6

5
for iter := combobox.Items.Count - 1 downto 0 do
begin
  index := combobox.Items.IndexOf(combobox.Items[iter]);
  if index < iter then
    combobox.Items.Delete(iter);
end;
于 2012-08-31T04:06:44.100 回答
2

我建议您每次只需重新填充组合框。这使得逻辑更简单:

ComboBox.Items.BeginUpdate;
try
  ComboBox.Clear;
  for Str in Values do
    begin
    if ComboBox.Items.IndexOf (Str) = -1 then
      ComboBox.Items.Add (Str);
    end;
finally
  ComboBox.Items.EndUpdate;
end;
于 2012-08-31T08:13:17.880 回答
2

只是为了让方法相互矛盾:一个人保持秩序,但随着项目数量的增加而变得越来越慢。另一个保持相对较快但不保持秩序:

procedure SortStringlist;
var
  i,index,itimer: integer;
  sl : TStringlist;
const
  numberofitems = 10000;
begin
  sl := TStringlist.Create;
  for i := 0 to numberofitems-1 do begin
    sl.Add(IntToStr(random(2000)));
  end;
  Showmessage(IntToStr(sl.Count));

  itimer := GetTickCount;
  sl.Sort;
  for I := sl.Count-1 downto 1 do begin
    if sl[i]=sl[i-1] then sl.Delete(i);
  end;
  Showmessage(IntToStr(sl.Count)+' Time taken in ms: '+IntToStr(GetTickCount-itimer));
  sl.free;
  sl := TStringlist.Create;
  for i := 0 to numberofitems-1 do begin
    sl.Add(IntToStr(random(2000)));
  end;
  Showmessage(IntToStr(sl.Count));

  itimer := GetTickCount;
  for i := sl.Count - 1 downto 0 do
  begin
  index := sl.IndexOf(sl[i]);
  if index < i then
    sl.Delete(i);
  end;
  Showmessage(IntToStr(sl.Count)+' Time taken in ms: '+IntToStr(GetTickCount-itimer));
end;
于 2012-08-31T17:31:37.493 回答
2

如果您不关心项目是否重新排序(或它们已经排序),TStrings可以为您完成工作 - 它消除了所有循环、删除和其他工作。(当然,它需要创建/销毁一个临时的TStringList,所以如果这对你来说是个问题,它就行不通了。)

var
  SL: TStringList;
begin
  ComboBox1.Items.BeginUpdate;
  try
    SL := TStringList.Create;
    try
      SL.Sorted := True; // Required for Duplicates to work
      SL.Duplicates := dupIgnore;
      SL.AddStrings(ComboBox1.Items);
      ComboBox1.Items.Assign(SL);
    finally
      SL.Free;
    end;
  finally
    ComboBox1.Items.EndUpdate;
  end;
end;

要与 Igor 的答案(包括 no BeginUpdate/EndUpdate)正确比较,请删除这些内容:

var
  SL: TStringList;
begin
  SL := TStringList.Create;
  try
    SL.Sorted := True; // Required for Duplicates to work
    SL.Duplicates := dupIgnore;
    SL.AddStrings(ComboBox1.Items);
    ComboBox1.Items.Assign(SL);
  finally
    SL.Free;
  end;
end;
于 2012-08-31T23:20:22.517 回答
0

您必须从源数据中删除重复项。

在大多数情况下,ComboBox 会在运行时填充数据,这意味着数据来自某个来源。这里基本上有两种情况:来自数据库的数据集和来自任何其他来源的字符串集合。在这两种情况下,您都可以在将任何内容插入 ComboBox 之前过滤掉重复项。

如果源是数据库中的数据集,只需使用 SQLDISTINCT关键字。

如果源是任何字符串集合,请使用@Smasher 在答案中提供的代码和平。

于 2012-08-31T11:52:18.133 回答
0

我之前曾多次遇到过这个问题,我使用了所有以前的方法,但我仍在使用它们,但你知道吗:我认为最好的方法,虽然这里没有提到,是子类 TComboBox,创建一个新方法(比如AddUnique ) 仅在先前不存在的情况下将字符串添加到组合中,否则它将删除它。这个解决方案一开始可能会花费一些额外的时间,但它会一劳永逸地解决问题。

于 2012-09-01T12:16:26.677 回答