20

C# では、ランダムなインデックスでリストから項目を取得しようとしています。取得したら、もう選択できないように削除したいと思います。これを行うには多くの操作が必要なようですが、リストからアイテムを簡単に抽出できる関数はありませんか? RemoveAt(index) 関数は無効です。戻り値のあるものが欲しいです。

私がやっていること:

List<int> numLst = new List<int>();
numLst.Add(1);
numLst.Add(2);

do
{
  int index = rand.Next(numLst.Count);
  int extracted = numLst[index]; 
  // do something with extracted value...
  numLst.removeAt(index);
}
while(numLst.Count > 0);

私がしたいこと:

List<int> numLst = new List<int>();
numLst.Add(1);
numLst.Add(2);

do
{
  int extracted = numLst.removeAndGetItem(rand.Next(numLst.Count)); 
  // do something with this value...
}
while(numLst.Count > 0);

そのような「removeAndGetItem」関数は存在しますか?

4

2 に答える 2

23

いいえ、メソッドが副作用を持っているか、有用な値を返す (つまり、エラー状態を示すだけではない) 場合は、純粋な関数のエチケットに違反するため、決して両方ではありません。

関数をアトミックに見せたい場合は、リストのロックを取得できます。これにより、リストを変更している間、他のスレッドが以下を使用していれば、リストにアクセスできなくなりますlock

public static class Extensions
{
    public static T RemoveAndGet<T>(this IList<T> list, int index)
    {
        lock(list)
        {
            T value = list[index];
            list.RemoveAt(index);
            return value;
        }
    }
}
于 2013-03-01T09:18:48.210 に答える
8
public static class ListExtensions
{
  public static T RemoveAndGetItem<T>(this IList<T> list, int iIndexToRemove}
  {
    var item = list[iIndexToRemove];
    list.RemoveAt(iIndexToRemove);
    return item;
  } 
}

これらは拡張メソッドと呼ばれ、 as として呼び出しますnew List<T>().RemoveAndGetItem(0)

拡張メソッドの考慮事項

渡したインデックスで例外処理を行います。これを行う前に、インデックスが 0 とリストのカウント内にあることを確認してください。

于 2013-03-01T09:12:53.167 に答える