2008-09-17 50 views
16

可以說我有一個Dictionary對象:在C#.NET 2.0中,反向執行foreach的簡單方法是什麼?

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

現在我想通過以相反的順序字典進行迭代。我不能使用簡單的for循環,因爲我不知道字典的鍵。一個的foreach很簡單:

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

但我怎麼能反向執行此?

回答

19

我會使用SortedList而不是字典。您仍然可以通過Key訪問它,但您也可以通過索引訪問它。

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); 

值得注意的是,排序列表存儲按鍵排序的鍵/值對。

28

字典或任何其他形式的散列表沒有排序。所以,你正在試圖做的是沒有意義的:)

+0

哦,是的。咄。我完全愚蠢。感謝:-) – Pandincus 2008-09-17 13:04:10

+0

如果您想要散列表類型查找以及陣列列表樣式序列排序,請使用SortedList。有人已經發布了一段代碼片段。 – Gishu 2008-09-17 13:41:33

+0

當然哈希表已經訂購! – 2011-11-04 12:28:49

1

這將是一個Dictionary<int, SomeObject> myDictionary,你會被做:

foreach(SomeObject _object in myDictionary.Values.Reverse()) 
{ 
} 
0

如果排序是最重要的,你可能在你一個堆棧和創建簡單的結構來存儲你的int,Object對。

18

如果您有.NET 3.5,則可以在IEnumerables上使用.Reverse()擴展方法。例如:

foeach (SomeObject o in myDictionary.Values.Reverse()) 
{ 
    // Do stuff to object 
} 
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 
} 
3

我同意@leppie,但認爲你應該得到一般問題的答案。這可能是因爲你的意思是一般而言,但意外地選擇了錯誤的數據結構。字典中的值的順序應被視爲實現特定的;根據文檔,它總是和鍵一樣的順序,但是這個順序也沒有被指定。

無論如何,沒有一種簡單的方法可以使foreach反向工作。它是使用類的枚舉器的語法糖,枚舉器只能向一個方向傳播。從技術上講,答案可能是「反向的收集,然後枚舉」,但我認爲這是在你只需要使用「倒退」的循環的情況下:

for (int i = myCollection.Length - 1; i >= 0; i--) 
{ 
    // do something 
}
0

如果你想要一本字典類型的集合但您需要維護插入順序,您可以查看KeyedCollection here

它是字典和列表之間的合併。這樣您就可以通過鍵或插入索引訪問集合中的元素。

唯一的問題是如果你的元素存儲在集合中必須有一個int鍵。如果你可以將其改爲字符串或其他類型(Guid Mabye)。由於收集1將搜索1的密鑰而不是1的索引。

0

標準for循環將是最好的。您不必擔心反轉收集的處理開銷。

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或提供了一個索引。說一本字典沒有秩序是不正確的:當然它有秩序。如果你知道它是什麼,那麼這個命令甚至可以是有用的。

對於你的問題的解決方案:我會說複製元素到一個數組,並使用上述方法來反向遍歷它。就像這樣:

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); 
    } 

} 

複製你的價值到一個數組可能看起來是一個壞主意,但取決於值的類型是不是真的那麼壞。你可能只是複製引用!

0

的字面解釋:

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 
} 
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]; 
    } 
} 
-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; 
} 
相關問題