17

辞書オブジェクトがあるとしましょう:

Dictionary myDictionary<int, SomeObject> = new Dictionary<string, SomeObject>();

ここで、辞書を逆の順序で繰り返します。辞書のキーがわからないため、単純なforループを使用できません。foreachは簡単です:

foreach (SomeObject object in myDictionary.Values)
{
    // Do stuff to object
}

しかし、どうすればこれを逆に実行できますか?

4

14 に答える 14

28

辞書またはその他の形式のハッシュテーブルには順序がありません。だからあなたがやろうとしていることは無意味です:)

于 2008-09-17T13:02:20.647 に答える
20

辞書の代わりに SortedList を使用します。キーでアクセスすることもできますが、インデックスでアクセスすることもできます。

SortedList sCol = new SortedList();

sCol.Add("bee", "Some extended string matching bee");
sCol.Add("ay", "value matching ay");
sCol.Add("cee", "Just a standard cee");

// Go through it backwards.
for (int i = sCol.Count - 1; i >=0 ; i--)
    Console.WriteLine("sCol[" + i.ToString() + "] = " + sCol.GetByIndex(i));

// Reference By Key
foreach (string i in sCol.Keys)
    Console.WriteLine("sCol[" + i + "] = " + sCol[i]);

// Enumerate all values
foreach (string i in sCol.Values)
    Console.WriteLine(i);

ソートされたリストには、キーのみでソートされたキーと値のペアが格納されることに注意してください。

于 2008-09-17T13:17:01.097 に答える
18

.NET 3.5を使用している場合は、IEnumerablesで.Reverse()拡張メソッドを使用できます。例えば:

foreach (object o in myDictionary.Values.Reverse())
{
     // Do stuff to object
}
于 2008-09-17T13:05:53.103 に答える
4

実際、C# 2.0 では、コンテナーを逆方向にトラバースする独自の反復子を作成できます。次に、その反復子を foreach ステートメントで使用できます。ただし、イテレータには、最初にコンテナをナビゲートする方法が必要です。単純な配列の場合は、次のように逆戻りできます。

static IEnumerable<T> CreateReverseIterator<T>(IList<T> list)
{
    int count = list.Count;
    for (int i = count - 1; i >= 0; --i)
    {
        yield return list[i];
    }
}

ただし、IList を実装していないか、インデクサーを提供していないため、Dictionary ではもちろんそれを行うことはできません。Dictionary に順序がないと言うのは正しくありません。もちろん順序があります。その順序は、それが何であるかを知っていれば役立ちます。

あなたの問題を解決するには:要素を配列にコピーし、上記の方法を使用して逆にトラバースします。このような:

static void Main(string[] args)
{
    Dictionary<int, string> dict = new Dictionary<int, string>();

    dict[1] = "value1";
    dict[2] = "value2";
    dict[3] = "value3";

    foreach (KeyValuePair<int, string> item in dict)
    {
        Console.WriteLine("Key : {0}, Value: {1}", new object[] { item.Key, item.Value });
    }

    string[] values = new string[dict.Values.Count];
    dict.Values.CopyTo(values, 0);

    foreach (string value in CreateReverseIterator(values))
    {
        Console.WriteLine("Value: {0}", value);
    }

}

値を配列にコピーするのは悪い考えのように思えるかもしれませんが、値の型によってはそれほど悪いことではありません。参照をコピーしているだけかもしれません。

于 2008-09-17T13:24:09.550 に答える
3

.NET 3.5がないため、逆拡張メソッドを使用していない場合は、独自のメソッドを実装できます。おそらく(必要に応じて)中間リストを生成し、次のように逆に繰り返します。

public static IEnumerable<T> Reverse<T>(IEnumerable<T> items)
{
    IList<T> list = items as IList<T>;
    if (list == null) list = new List<T>(items);
    for (int i = list.Count - 1; i >= 0; i-- )
    {
        yield return list[i];
    }
}
于 2008-09-17T14:14:52.377 に答える
3

私は@leppieに同意しますが、一般的に質問への回答に値すると思います. 質問が一般的なものであることを意図していたのに、誤って不適切なデータ構造を選択した可能性があります。ディクショナリ内の値の順序は、実装固有と見なす必要があります。ドキュメントによると、常にキーと同じ順序ですが、この順序も指定されていません。

foreachとにかく、逆に機能させる簡単な方法はありません。クラスの列挙子を使用することはシンタックス シュガーであり、列挙子は一方向にしか移動できません。技術的には、答えは「コレクションを逆にしてから列挙する」かもしれませんが、これは「後方」for ループを使用する必要がある場合だと思います。

for (int i = myCollection.Length - 1; i >= 0; i--)
{
    // do something
}
于 2008-09-17T13:09:43.313 に答える
1

それはになりDictionary<int, SomeObject> myDictionaryます、そしてあなたはそれをするでしょう:

foreach(SomeObject _object in myDictionary.Values.Reverse())
{
}
于 2008-09-17T13:05:45.960 に答える
1

.NET 2.0で思いつく唯一の方法は、最初にすべての値をリストにコピーし、リストを逆にしてから、そのリストでforeachを実行することです。

Dictionary<int, object> d;
List<object> tmplist;
foreach (object o in d.Values) tmplist.Add(s);
tmplist.Reverse();
foreach (object o in tmplist) {
    //Do stuff
}
于 2008-09-17T13:06:08.827 に答える
1

文字通りの答え:

Dictionary<int, SomeObject>  myDictionary = new Dictionary<int, SomeObject>();

foreach (var pair in myDictionary.OrderByDescending(i => i.Key))
{
    //Observe pair.Key
    //Do stuff to pair.Value
}
于 2008-09-17T13:54:52.127 に答える
0

順序が最も重要な場合は、スタックを作成して、intとObjectのペアを格納するための単純な構造体を作成できます。

于 2008-09-17T13:05:52.637 に答える
0

辞書タイプのコレクションが必要であるが、挿入順序を維持する必要がある場合は、 ここで KeyedCollection を調べることができます

辞書とリストの融合です。そうすれば、キーまたは挿入インデックスを介してコレクション内の要素にアクセスできます。

唯一の問題は、コレクションに格納されている要素に int キーが必要な場合です。それを文字列または別のタイプ(Guid Mabye)に変更できる場合。コレクション1は 1 のインデックスではなく 1 のキーを検索するためです。

于 2008-09-17T13:13:10.887 に答える
0

標準forループが最適です。コレクションを逆にする処理のオーバーヘッドについて心配する必要はありません。

于 2008-09-17T13:15:58.523 に答える
0

LinqBridgeを使用して、.NET 2.0 でLINQ to Objects Enumerable.Reverse() 関数を使用できます。

于 2008-09-17T13:42:39.567 に答える
-2
foreach (Sample in Samples)

try the following:

Int32 nEndingSample = Samples.Count - 1;

for (i = nEndingSample; i >= 0; i--)
{
     x = Samples[i].x;
     y = Samples[i].y;
}
于 2012-09-01T03:54:16.940 に答える