Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Removing Duplicate Entries 2

Status
Not open for further replies.

BobbaFet

Programmer
Feb 25, 2001
903
0
0
NL
Hey all,

Ok so what is going on is this:
I've made a file processing utility and that in itself
works fine. But here's something I've been wanting to add:

I want to remove duplicate entries, sometimes there is
duplicate data in the listbox that I am using. And here
lies my problem:

I can easily write a procedure that will remove double
entries but it can't handle it when the same data is in
there 3 or more times which causing the famous "index out
of bounds" error and I haven't a clue in what I am doing
wrong.

The way I do it that works for double entries:
Code:
procedure RemoveDuplicateEntries;
var i,j: integer;
begin
for i := ListBox1.Items.Count - 1 downto 0 do
     begin
     for j := i - 1 downto 0 do
          if ListBox1.Items.Strings[i] = ListBox1.Items.Strings[j] then
               ListBox1.Items.Delete(j);
     end;
end;

[bobafett] BobbaFet [bobafett]

Code:
if not Programming = 'Severe Migraine' then
                       ShowMessage('Eureka!');
faq102-5352
 
let just say we have a List with this Items:

Index Item String
----- -----------
0 Item1
1 Item1
2 Item2
3 Item3
4 Item3
5 Item3

We have 6 items here.
Index #5 is the first we have in the iteration.
According to your code, index #4 and #3 will be deleted.
And So, Items count will be 4, correct?
If we go to the next i in iteration (for i := ListBox1.Items.Count - 1 downto 0 do ...),
the value of i will be 5.
But the items in list is only 4, so the "index out of bounds" message will appear here.

let me make a little changes in your code:
Code:
procedure RemoveDuplicateEntries;
var i,j, k: integer;
begin
  for i := ListBox1.Items.Count - 1 downto 0 do
  begin
    k:= i;
    if k >= ListBox1.Items.Count then
      k:= ListBox1.Items.Count-1;
    for j := k - 1 downto 0 do
      if ListBox1.Items.Strings[k] = ListBox1.Items.Strings[j] then
        ListBox1.Items.Delete(j); //this line removed
  end;
end;

It is not tested yet, but I hope it works


 
Yes! Got it to work!

It just needed a minor adjustment >

Code:
procedure RemoveDuplicateEntries;
var i,j, k: integer;
S: string;
begin
  for i := ListBox1.Items.Count - 1 downto 0 do
  begin
    k:= i;
    if k >= ListBox1.Items.Count then
      k:= ListBox1.Items.Count-1;
    S := ListBox1.Items.Strings[k];
    for j := k - 1 downto 0 do
      if S = ListBox1.Items.Strings[j] then
        ListBox1.Items.Delete(j); //this line removed
  end;
end;

It works now :D It still gave the out for bounds for the J loop.
I fixed it by setting the value of ListBox1.Items.Strings[k] to S variable.

[bobafett] BobbaFet [bobafett]

Code:
if not Programming = 'Severe Migraine' then
                       ShowMessage('Eureka!');
faq102-5352
 
A slight variation that I use:

Assuming ListBox1 contains:

Item 1
Item 1
Item 2
Item 3
Item 4
Item 4
Item 5
Item 6
Item 6
Item 6

Code:
procedure TForm1.Button1Click(Sender: TObject);

var
  a, b  : integer;

begin
    for a := 0 to ListBox1.Items.Count - 1 do
      for b := ListBox1.Items.Count - 1 downto a + 1 do
        if ListBox1.Items[a] = Listbox1.Items[b] then
          ListBox1.Items.Delete(a);
end;

leaves ListBox1 with:

Item 1
Item 2
Item 3
Item 4
Item 5
Item 6


Hope this helps.

[vampire][bat]
 
It doesn't have to be that complicated. All you need is something like this:
Code:
procedure RemoveDuplicates(AListBox:TListBox);
var
  i:integer;
begin
  with AListBox do
    for i := Items.Count - 1 downto 0 do
      if Items.IndexOf(Items[i]) < i then
        Items.Delete(i);
end;
You can test it with this:
Code:
procedure TForm1.Button1Click(Sender: TObject);
begin
  RemoveDuplicates(ListBox1)
end;
Of course, if you prefer, you can put the routine directly inside the click event handler.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top