私はコンボボックスを持っていると言います
apples
apples
pears
oranges
oranges
見せてもらいたい
apples
pears
oranges
これどうやってするの?
私はコンボボックスを持っていると言います
apples
apples
pears
oranges
oranges
見せてもらいたい
apples
pears
oranges
これどうやってするの?
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;
アイテムが並べ替えられても (または既に並べ替えられていても) 気にしない場合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;
毎回コンボボックスを補充することをお勧めします。これにより、ロジックが単純になります。
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;
メソッドを相互に配置するだけです。順序は保持されますが、アイテムの数が増えるとますます遅くなります。もう 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;
ソース データから重複を削除する必要があります。
ほとんどのシナリオでは、実行時に ComboBox にデータが入力されます。つまり、データは何らかのソースから取得されます。ここには基本的に 2 つのシナリオがあります。データベースからのデータセットと、他のソースからの文字列のコレクションです。どちらの場合も、ComboBox に何かを挿入する前に重複を除外します。
ソースがデータベースからのデータセットである場合は、単純に SQLDISTINCT
キーワードを使用します。
source が文字列のコレクションである場合は、@Smasher の回答で提供されている平和なコードを使用してください。
私は以前にこの問題に何度か直面し、以前のすべてのアプローチを使用し、まだそれらを使用していますが、知っていますか: ここでは言及されていませんが、TComboBox をサブクラス化して新しいメソッドを作成するのが最善の方法だと思います (たとえば、 AddUnique ) は、以前に存在しない場合にのみ文字列をコンボに追加し、それ以外の場合はドロップします。この解決策は、最初は時間がかかる場合がありますが、問題は完全に解決されます。