从TStringList中删除字符串

7

我有一个带有项目的列表框或列表视图。我还有一个与列表框/列表视图中相同项目(字符串)的字符串列表。我想从字符串列表中删除所有在列表框/列表视图中选择的项目。

如何实现?

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个回答

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

18

窍门在于倒序运行循环:

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

这种方式,删除一个元素只会改变列表后面元素的索引位置,而这些元素已经被处理过了。


@maxfax 有谁先后有什么关系呢? - David Heffernan
2
@maxfax Andreas 在几秒钟前回答了。将鼠标悬停在显示“XX 分钟前”的文本上以查看时间戳。另一方面,我首先解释了为什么它有效!! ;-) - David Heffernan
4
@maxfax说:“不过我觉得我的答案更好,因为我很优秀地在二元减法运算符周围添加了空格!”(只是开玩笑!) - Andreas Rejbrand
3
实际上,我要说你很有眼光,使用了Count-1而不是pred(Count) - David Heffernan

10

Andreas和David提供的解决方案假设ListBox和StringList中的字符串顺序完全相同。这是一个很好的假设,因为您没有表明另外一种情况,但如果不是这样,您可以使用StringList的IndexOf方法来查找字符串的索引(如果StringList已经排序,则使用Find方法)。类似这样:

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;

我认为你可以非常确定maxfax正在同步维护这两个列表,因此不需要做出任何假设。 - David Heffernan

5
把它换个思路,改为添加而非删除,如何?
StringList1.Clear;
for i:=0 to ListBox.Count-1 do
  if not ListBox.Selected[i] then StringList1.Add(ListBox.Items(i));

嗯,这对我来说更有意义,但是问题本身似乎基本上就很混乱。 - Warren P
@warren 你通常如何迭代列表并删除一些但不是全部的项目? - David Heffernan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接