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

アイテムが並べ替えられても (または既に並べ替えられていても) 気にしない場合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 に答える
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

メソッドを相互に配置するだけです。順序は保持されますが、アイテムの数が増えるとますます遅くなります。もう 1 つは比較的高速のままですが、順序を維持しません。

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 に答える
0

ソース データから重複を削除する必要があります。

ほとんどのシナリオでは、実行時に ComboBox にデータが入力されます。つまり、データは何らかのソースから取得されます。ここには基本的に 2 つのシナリオがあります。データベースからのデータセットと、他のソースからの文字列のコレクションです。どちらの場合も、ComboBox に何かを挿入する前に重複を除外します。

ソースがデータベースからのデータセットである場合は、単純に SQLDISTINCTキーワードを使用します。

source が文字列のコレクションである場合は、@Smasher の回答で提供されている平和なコードを使用してください。

于 2012-08-31T11:52:18.133 に答える
0

私は以前にこの問題に何度か直面し、以前のすべてのアプローチを使用し、まだそれらを使用していますが、知っていますか: ここでは言及されていませんが、TComboBox をサブクラス化して新しいメソッドを作成するのが最善の方法だと思います (たとえば、 AddUnique ) は、以前に存在しない場合にのみ文字列をコンボに追加し、それ以外の場合はドロップします。この解決策は、最初は時間がかかる場合がありますが、問題は完全に解決されます。

于 2012-09-01T12:16:26.677 に答える