C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[9]: List<>での検索Remove


(過去ログ 23 を表示中)

[トピック内 16 記事 (1 - 16 表示)]  << 0 >>

■10106 / inTopicNo.1)  List<>での検索Remove
  
□投稿者/ てぃあの (1回)-(2007/11/11(Sun) 20:45:32)

分類:[C#] 

C#にて、現状は以下のソースコードのようにしていますが、foreach等を使ったうまいやり方はないのでしょうか?

private static List<Hoge> _objs = new List<Hoge>(); 

for( int i = 0; i < _objs.Count; i++ ) {
    _objs[i].update();
    if( _objs[i].isEnd ) { // 役目は終わったか?...
        _objs.RemoveAt(i--);
    }
}

気持ち的には

foreach( Hoge obj in _objs ) {
    obj.update();
    if( obj.isEnd ) {
        _objs.Remove(obj);
    }
}

ができたらいいのに(ちがうな…のような書き方ないかな?)と思いまして。

引用返信 編集キー/
■10110 / inTopicNo.2)  Re[1]: List<>での検索Remove
□投稿者/ 渋木宏明(ひどり) (540回)-(2007/11/11(Sun) 21:05:27)
渋木宏明(ひどり) さんの Web サイト
> C#にて、現状は以下のソースコードのようにしていますが、foreach等を使ったうまいやり方はないのでしょうか?

無いす。

「出来ないよ」ってヘルプのどこかに書いてあったはず。

引用返信 編集キー/
■10111 / inTopicNo.3)  Re[1]: List<>での検索Remove
□投稿者/ @echo (14回)-(2007/11/11(Sun) 21:22:12)
No10106 (てぃあの さん) に返信
> C#にて、現状は以下のソースコードのようにしていますが、foreach等を使ったうまいやり方はないのでしょうか?

_objs.RemoveAll(delegate(Hoge obj)
{
  obj.update();
  return obj.isEnd;
});

ではダメなのでしょうか?

引用返信 編集キー/
■10116 / inTopicNo.4)  Re[2]: List<>での検索Remove
□投稿者/ 渋木宏明(ひどり) (541回)-(2007/11/11(Sun) 22:38:19)
渋木宏明(ひどり) さんの Web サイト
>現状は以下のソースコードのようにしていますが

あれ? よく見るとコレまずくありません?

Remove() したら、インデックスが1個前に詰まりますよ?

> _objs.RemoveAll(delegate(Hoge obj)
> {
> obj.update();
> return obj.isEnd;
> });
>
> ではダメなのでしょうか?

ならおkですね。

コレクションを直接 foreach で回しつつ、削除しちゃダメということで。

等価なコードは

foreach(Hoge obj n _objs.ToArray())
{
obj.update();
if (obj.isEnd) _objs.Remove(obj);
}

みたいな感じ。

仕方ないけど、ToArray() がちょっともったいない感じ。

引用返信 編集キー/
■10119 / inTopicNo.5)  Re[3]: List<>での検索Remove
□投稿者/ επιστημη (641回)-(2007/11/11(Sun) 23:01:39)
επιστημη さんの Web サイト
2007/11/11(Sun) 23:51:12 編集(投稿者)
> foreach(Hoge obj n _objs.ToArray()) {
>   obj.update();
>   if (obj.isEnd) _objs.Remove(obj);
> }

これだと_objs.Remove(obj)んとこで毎回_objsを頭っから舐めてobjを探しちゃうよな。

List<Hoge> tmp = new List<Hoge>();
foreach ( Hoge obj in _objs ) {
  obj.update();
  if ( !obs.isEnd ) tmp.Add(obj) // 必要なもんだけコピって
}
_objs = tmp; // 差し替え

とかいかがでしょ。

引用返信 編集キー/
■10121 / inTopicNo.6)  Re[4]: List<>での検索Remove
□投稿者/ ぽぴ王子 (288回)-(2007/11/11(Sun) 23:44:37)
ぽぴ王子 さんの Web サイト
昔似たような質問に回答した気がします。

そのときは「別リストを作って削除 *しない* ものを追加していく」とか

private static List<Hoge> _objs = new List<Hoge>();
private static List<Hoge> _objs2 = new List<Hoge>();

for( int i = 0; i < _objs.Count; i++ ) {
    _objs[i].update();
    if( !_objs[i].isEnd ) { // 役目は終わったか?...
        _objs2.Add(_objs[i]);
    }
}

# しまった、これεπιστημηさんが先に書いてるや…

for で ++ じゃなく -- で検索、とか

private static List<Hoge> _objs = new List<Hoge>(); 

for( int i = _objs.Count-1; i >= 0; i-- ) {
    _objs[i].update();
    if( _objs[i].isEnd ) { // 役目は終わったか?...
        _objs.RemoveAt(i);
    }
}

そんなことを書いたような気がします。

なんにせよ、ひどりさんも書かれているとおり foreach の途中でリストの操作をしてはダメです。

引用返信 編集キー/
■10125 / inTopicNo.7)  Re[5]: List<>での検索Remove
□投稿者/ てぃあの (3回)-(2007/11/12(Mon) 00:10:54)
むぅ…ないんですね。
STLのときもちょっと考えたんですけど、現状のようなコードしか思いつかなくて。

※気持ち的には…のコードはダメなのはわかっていますョ。

そもそも現状のコードは作法的にどうなんでしょう?まずかったりしますでしょうか?

実は質問自体が悪いのかな…。
みなさんはそもそも、Listの中のオブジェクトの一部が用済みになったときってどうしてるんでしょうか?

※思ったより短時間にコメントがたくさんついて大変うれしいです。

引用返信 編集キー/
■10128 / inTopicNo.8)  Re[6]: List<>での検索Remove
□投稿者/ επιστημη (642回)-(2007/11/12(Mon) 00:18:33)
επιστημη さんの Web サイト
> STLのときもちょっと考えたんですけど、現状のようなコードしか思いつかなくて。

参考: STLだと↓こんな感じ
http://blogs.wankuma.com/episteme/archive/2007/11/12/107752.aspx

引用返信 編集キー/
■10133 / inTopicNo.9)  Re[7]: List<>での検索Remove
□投稿者/ てぃあの (5回)-(2007/11/12(Mon) 00:38:18)
No10128 (επιστημη さん) に返信

objs.erase(remove_if(objs.begin(), objs.end(), update_and_validate), objs.end());
これ!ぺっかーん(!)って感じで思い出しました!!

仕事のときは先輩にこれって言われてやってましたわー。
記憶が正しければ、必要なものを前詰めにして、remove_ifの戻り値が不要な箇所の先頭indexなんでしたっけ?
そんでeraseでちょっきん!って感じだったと思うんですけど。
処理的にもバブルソートみたいな感じで詰め替えて行くからそんなんでもない…だったような(The うるおぼえ)。

※結局…C#ではどういう作法がいいんでしょうかね…?

引用返信 編集キー/
■10134 / inTopicNo.10)  Re[6]: List<>での検索Remove
□投稿者/ 渋木宏明(ひどり) (545回)-(2007/11/12(Mon) 00:49:26)
渋木宏明(ひどり) さんの Web サイト
> そもそも現状のコードは作法的にどうなんでしょう?まずかったりしますでしょうか?

バグってマス (^^;

> みなさんはそもそも、Listの中のオブジェクトの一部が用済みになったときってどうしてるんでしょうか?

C#2.0 でキレイなのは、@echo さんが書いてた RemoveAll(Predict<T> match) かと。

引用返信 編集キー/
■10135 / inTopicNo.11)  Re[7]: List<>での検索Remove
□投稿者/ επιστημη (644回)-(2007/11/12(Mon) 00:59:02)
επιστημη さんの Web サイト
>>みなさんはそもそも、Listの中のオブジェクトの一部が用済みになったときってどうしてるんでしょうか?
> C#2.0 でキレイなのは、@echo さんが書いてた RemoveAll(Predict<T> match) かと。

RemoveAllできるのがListのみなのがショボーンです。
せめてIListに用意しといてくれたらLinkedListでも使えただろに、
ライブラリ屋さんの意図が読めません。
引用返信 編集キー/
■10136 / inTopicNo.12)  Re[7]: List<>での検索Remove
□投稿者/ てぃあの (7回)-(2007/11/12(Mon) 00:59:59)
No10134 (渋木宏明(ひどり) さん) に返信
>>そもそも現状のコードは作法的にどうなんでしょう?まずかったりしますでしょうか?
> 
> バグってマス (^^;

for( int i = 0; i < _objs.Count; i++ ) {
    _objs[i].update();
    if( _objs[i].isEnd ) { // 役目は終わったか?...
        _objs.RemoveAt(i--);
    }
}

ありぃ?これ↑ダメ?
はずかぴぃ〜。

RemoveAll(Predict<T> match) で書いてみますw

引用返信 編集キー/
■10138 / inTopicNo.13)  Re[8]: List<>での検索Remove
□投稿者/ επιστημη (645回)-(2007/11/12(Mon) 01:04:36)
επιστημη さんの Web サイト
2007/11/12(Mon) 01:04:54 編集(投稿者)
> for( int i = 0; i < _objs.Count; i++ ) {
>     _objs[i].update();
>     if( _objs[i].isEnd ) { // 役目は終わったか?...
>         _objs.RemoveAt(i--);
>     }
> }
> 
> ありぃ?これ↑ダメ?

3番目が引っ掛かったとすると
_objs.RemoveAt(i--) だから 
3番目を引っこ抜いて、iが2になって、i++で3に戻るから
元々(削除前の)4番目が次の対象になりますよね。
...よさげな気がすんだけど。

引用返信 編集キー/
■10139 / inTopicNo.14)  Re[9]: List<>での検索Remove
□投稿者/ 渋木宏明(ひどり) (546回)-(2007/11/12(Mon) 01:34:03)
渋木宏明(ひどり) さんの Web サイト
> _objs.RemoveAt(i--) だから
> 3番目を引っこ抜いて、iが2になって、i++で3に戻るから

デクリメントしてたんだ (^^;
動くんだろうけど、別な意味でイヤん。

引用返信 編集キー/
■10140 / inTopicNo.15)  Re[8]: List<>での検索Remove
□投稿者/ 渋木宏明(ひどり) (547回)-(2007/11/12(Mon) 01:35:36)
渋木宏明(ひどり) さんの Web サイト
> RemoveAllできるのがListのみなのがショボーンです。

.NET3.5 だと RemoveAll() 他が拡張メソッドで書きなおされているはずなので、List 以外にも使えそうな気が。


引用返信 編集キー/
■10141 / inTopicNo.16)  Re[9]: List<>での検索Remove
□投稿者/ てぃあの (9回)-(2007/11/12(Mon) 01:52:02)
あぁ、はずかしぃ感じじゃなくて良かったw(いや〜んって言われたけどw)

ということで結果 RemoveAll(Predict<T> match) で無事動いた&まぁ綺麗なんではないかと。

みなさま、いろいろありがとうございました。

解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -