Delphi Tips(8) TStringListのDeleteについて

TStringListで特定のStringsを削除するケースはよくあると思うのだが、
for文で回して、IF文で特定のStringsをDeleteしようとすると、インデックスが範囲を超えてしまう。

原因はDeleteした瞬間に、インデックスがづれてしまうためなのだが...

どうすればいいのか少々ハマったのでメモっておきます

◆Delete処理 誤り(インデックスの範囲を超える)

処理:A,B,Cの文字をStringListに入れて、Bだけ削除する

procedure TForm2.Button1Click(Sender: TObject);
var
  SL: TStringList;
  I: Integer;
begin
  SL := TStringList.Create;

  SL.add('A');
  SL.add('B');
  SL.add('C');

  for I := 0 to SL.Count - 1 do
    if SL.Strings[I] = 'B' then
      SL.Delete(I);

 showmessage(IntToStr(SL.cout));

end;

for文中ではIの変数は操作できない...
シンプルで良い方法はないか考えたが、下記のように修正することにした。

◆Delete処理 修正版

処理:A,B,Cの文字をStringListに入れて、Bだけ削除する

procedure TForm2.Button1Click(Sender: TObject);
var
  SL, SL2: TStringList; // SL2追加
  I: Integer;
begin
  SL := TStringList.Create;
  SL2 := TStringList.Create; // SL2追加

  SL.add('A');
  SL.add('B');
  SL.add('C');

  for I := 0 to SL.Count - 1 do
    if SL.Strings[I] <> 'B' then
      SL2.add(SL.Strings[I]); // SL2.ADD に変更
  SL := SL2; // SL2をSLにコピーする

 showmessage(IntToStr(SL.cout));

  SL2.free;

end;

 

 

Values、Namesが面白かったので、ついでに記載しておきます
Valuesを使うと、多次元の配列が表現できます。
上記のDeleteサンプルのようにValuesを使った場合の、削除方法です。

◆Values版のDelete処理
処理:大石、石川、斉藤の住所を登録し、石川のみ削除する

procedure TForm2.Button1Click(Sender: TObject);
var
  SL1, SL2, SL3: TStringList;
  I: Integer;
begin
  SL1 := TStringList.Create;
  SL2 := TStringList.Create;
  SL3 := TStringList.Create;

  SL1.values['名前'] := '大石';
  SL1.values['住所'] := '島田';
  SL2.values['大石'] := SL1.Text;

  SL1.values['名前'] := '石川';
  SL1.values['住所'] := '島田';
  SL2.values['石川'] := SL1.Text;

  SL1.values['名前'] := '斉藤';
  SL1.values['住所'] := '島田';
  SL2.values['斉藤'] := SL1.Text;

  for I := 0 to SL2.Count - 1 do
    if SL2.Names[I] <> '石川' then
      SL3.values[SL2.Names[I]] := SL2.values[SL2.Names[I]];

  SL2 := SL3;

  for I := 0 to SL2.Count - 1 do
    showmessage(SL2.values[SL2.Names[I]]);

 SL1.free;
  SL3.free;

end;

Delphi Tips(8) TStringListのDeleteについて” への2件のフィードバック

  1. TStringsの派生クラスで要素を削除するときはfor i := SL.Count – 1 downto 0 doのように逆方向から処理をする、という手をよく使います。

  2. うわ!その手がありましたか。気付かなかったです。
    今度試してみます。コメントありがとうございました。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です