8

I have a List Box or a List View with items. And I have a String List with the same items (strings) as the List Box/List View. I want to delete all selected items in the List Box/List View from the String List.

How to do?

for i:=0 to ListBox.Count-1 do
  if ListBox.Selected[i] then
    StringList1.Delete(i); // I cannot know exactly an index, other strings move up

4 Answers 4

22
for i := ListBox.Count - 1 downto 0 do
  if ListBox.Selected[i] then
    StringList1.Delete(i);
Sign up to request clarification or add additional context in comments.

Comments

19

The trick is to run the loop in reverse order:

for i := ListBox.Count-1 downto 0 do
  if ListBox.Selected[i] then 
    StringList1.Delete(i);

This way, the act of deleting an item only changes the indices of elements later in the list, and those elements have already been processed.

4 Comments

@maxfax What does it matter who is first?
@maxfax Andreas answered a few seconds earlier. Hover the mouse over the text that says XX mins ago to see the time stamp. On the other hand, I explained why it works first!! ;-)
@maxfax: However, my answer is much better because I had the excellent taste of surrounding the binary subtraction operator with spaces! (Just kidding!)
@Andreas Actually, I'd say that you had the good taste to use Count-1 rather than pred(Count)!!
10

Solution provided by Andreas and David assumes that the strings are exactly in same order in both ListBox and StringList. This is good assumption as you don't indicate otherwise, but in case it is not true you can use StringList's IndexOf method to find the index of the string (if the StringList is sorted, use Find instead). Something like

var x, Idx: Integer;
for x := ListBox.Count - 1 downto 0 do begin
   if ListBox.Selected[x] then begin
      idx := StringList.IndexOf(ListBox.Items[x]);
      if(idx <> -1)then StringList.Delete(idx);
   end;
end;

1 Comment

I think you can be pretty sure that maxfax is maintaining the two lists in sync and so doesn't need to assume anything
5

How about doing it the other way round (adding instead of deleting)?

StringList1.Clear;
for i:=0 to ListBox.Count-1 do
  if not ListBox.Selected[i] then StringList1.Add(ListBox.Items(i));

2 Comments

Well, this makes a lot more sense to me, but then, the question itself seems fundamentally confused.
@warren how do you normally iterate over a list and delete some but not all items?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.