2012-04-10 66 views
0

列表:重新排序清單開始在給定的位置

List<int> list1 = new List<int>(){ 0, 1, 2, 3, 4, 5, 6 }; 

讓我們說,我們要重新排序。開始的時候應該是在 「2」 號

// 2,3,4,5,6,0,1 

或5號

// 5,6,0,1,2,3,4 

你如何用C#做呢?

原因:想象一下,您有一個列表中給定數字的索引(數字3,索引3)。你想從右邊獲得第二個數字 - 它會是5.

不幸的是,如果起始數字是在列表末尾(數字5和6) - 超出範圍的異常將被拋出,因爲沒有7和8!

這個想法是重新排序列表!

  • 我們輸入Nr。 5 - 我們得到0(5,6,0)。
  • 我們輸入Nr。 6 - 我們得到1(6,0,1)等。

或者也許還有其他一些解決此問題的方法?

回答

2

您不需要重新排列列表。你可以用下面的函數獲取數量:

int GetNumber(List<int> list, int fromValue, int index) 
{ 
    return list[(list.IndexOf(fromValue) + index) % list.Count()]; 
} 

你可以調用該函數是這樣的:

List<int> list1 = new List<int>(new[] { 0, 1, 2, 3, 4, 5, 6 }); 
int number = GetNumber(list1, 5, 2); // number = 0 
+0

偉大的除了馬特的答案!謝謝! – Alex 2012-04-10 15:55:51

+0

你確定' - 1'是必要的嗎? – 2012-04-10 15:56:02

+0

@ OlivierJacot-Descombes:我添加了'-1'來匹配OP的預期行爲(索引3 =右邊兩位)。 – 2012-04-10 15:59:02

4

更好的方法是使用mod運算符%。當你用另一個int分隔一個int時,這會給你餘數。其工作原理是這樣的:

int nextIndex = (currentIndex + offset) % length; 

所以,如果你目前的指數是5,你的偏移量是2,你的長度爲6,則:

5 + 2 = 7 
7/6 = 1 remainder 1 (or 7 mod 6 = 1) 
therefore nextIndex = 1 
+0

謝謝你的解釋! – Alex 2012-04-10 16:00:51

3

一點點的LINQ幾乎可以做到這一點容易:

List<int> list1 = new List<int>(new[] { 0, 1, 2, 3, 4, 5, 6 }); 

var numToStart = 4; 

//reorderedList will be {4,5,6,0,1,2,3} 
var reorderedList = list1.Skip(numToStart).Concat(list1.Take(numToStart)); 
+0

這應該可行,但它會重新創建整個列表,而不是僅移動項目,或者由其他人提供的不涉及任何列表變化的解決方案。 – Servy 2012-04-10 15:48:21

+0

不,不是;它以方法定義的特定方式迭代列表。 Skip()和Take()不需要在內部創建新的集合,如OrderBy()和GroupBy();他們只需按照名稱隱含的扭曲來枚舉它們的源代碼集合(例如不屈服第一個X項目,或僅屈服第一個X項目)。現在,如果你需要實際堅持重新排序的項目,那麼是的,這不會是就地,但這似乎並不是一個要求,而就地解決方案會更復雜。 – KeithS 2012-04-10 15:51:28

+0

OP的要求將涉及將查詢的結果存儲爲列表。如果你沒有,並且每次只是執行這個查詢,那麼你將一個O(1)列表查找變成一個O(n)查找,所以它仍然是一個非常劣質的解決方案。 – Servy 2012-04-10 15:55:36