2011-04-03 81 views
1

我有一個ArrayList字符串,看起來如下,我想輸出一個新的ArrayList排序在一個特定的方式。但不確定排序的好方法。幫助將非常感激!C# - 排序字符串ArrayList

原件(可以是任何隨機順序):

1:1 
0:0 
0:1 
2:1 
1:0 
2:0 

輸出:

2:0 
2:1 
1:0 
1:1 
0:0 
0:1 
+0

@Mike - 有沒有可能來存儲信息的對象,而不是字符串?即他們需要是字符串,還是隻有當他們輸出? – Pandincus 2011-04-03 02:50:39

+0

@Pandincus:我想再次輸出它們作爲排序的字符串。但是,如果這使得它更容易,我想這會很好。 – 2011-04-03 02:53:40

+0

@Mike - 另外,你使用的是什麼版本的.NET Framework? – Pandincus 2011-04-03 02:56:21

回答

1

雖然我認爲其他答案都是現成的,但我會假設您不熟悉他們使用的.NET 2.0和.NET 3.5的一些功能。讓我們一步一個腳印吧。

所以你給出一個ArrayList持以下資料:

{ "1:1", "0:0", "0:1", "2:1", "1:0", "2:0" } 

首先,什麼是錯誤的使用正則表達式;也許是一個小小的表現處罰如果字符串真的如此簡單,你可以用Split

string[] s = myArray[i].Split(new[] { ':' }); 
int val1 = int.Parse(s[0]); 
int val2 = int.Parse(s[1]); 

不過,既然你說你正在使用.NET 4,你真的不應該使用ArrayList在所有 - 注意,它需要你將你的值轉換爲適當的類型,例如string mystring = myArray[i] as string

有很多很棒的功能,你沒有利用,如泛型(在.NET Framework 2.0以來)。讓我們編寫一個給定爲ArrayList的函數,但返回排序後的通用List<string>(僅包含字符串的列表)。讓我們一起來看看:

/// <summary> 
/// This method takes in an ArrayList of unsorted numbers in the format: a:b 
/// and returns a sorted List<string> with a descending, b ascending 
/// <summary> 
public List<string> SortMyValues(ArrayList unsorted) 
{ 
    // Declare an empty, generic List of type 'TwoNumbers' 
    List<MyTuple> values = new List<MyTuple>(); 
    foreach (object item in unsorted) 
    { 
     char[] splitChar = new char[] { ':' }; 
     string itemString = item as string; 
     string[] s = itemString.Split(splitChar); 
     values.Add(new MyTuple{ 
      FirstNumber = int.Parse(s[0]), 
      SecondNumber = int.Parse(s[1]) 
     }); 
    } 
    // Sort the values 
    values.Sort(); 
    // Return a list of strings, in the format given 
    List<string> sorted = new List<string>(); 
    foreach (MyTuple item in values) 
    { 
     sorted.Add(item.FirstNumber + ":" + item.SecondNumber); 
    } 
    return sorted; 
} 

public class MyTuple : IComparable { 
    public int FirstNumber { get; set; } 
    public int SecondNumber { get; set; } 

    public int CompareTo(object obj) 
    { 
     if (obj is MyTuple) 
     { 
      MyTuple other = (MyTuple)obj; 

      // First number descending 
      if (FirstNumber != other.FirstNumber) 
      return other.FirstNumber.CompareTo(FirstNumber); 
      // Second number ascending 
     return SecondNumber.CompareTo(other.SecondNumber); 
     } 
     throw new ArgumentException("object is not a MyTuple"); 
    } 
} 

現在,上面的代碼工作,但真的長。請注意,您必須創建一個類來保存這兩個值,使該類實現IComparable等等,非常討厭!

.NET 3.5推出了一些偉大的功能,包括匿名類型LINQ。讓我們更改我們的代碼以使用這兩個功能。

/// <summary> 
/// This method takes in an ArrayList of unsorted numbers in the format: a:b 
/// and returns a sorted List<string> with a descending, b ascending 
/// <summary> 
public List<string> SortMyValues(ArrayList unsorted) 
{ 
    // First, cast every single element of the given ArrayList to a string 
    // The Cast<T> method will do this, and return an enumerable collection 
    return unsorted.Cast<string>() 
     // Now, let's take this string data and create our objects that will hold two numbers 
     .Select(item => { 
      // This is the body of an anonymous method with one parameter, which I called 'item' 
      // This anonymous method will be executed for every element in the collection 
      string[] s = item.Split(new[] { ':' }); 
      // Here we create a new anonymous type holding our numbers 
      // No need to define a new dummy class! 
      return new { 
       FirstNumber = int.Parse(s[0]), 
       SecondNumber = int.Parse(s[1]) 
      }; 
     }) 
     // Now that we've got our objects, let's sort them 
     .OrderByDescending(x => x.FirstNumber) 
     .ThenBy(x => x.SecondNumber) 
     // Finally, now that we're sorted properly, let's format our string list output 
     .Select(x => x.FirstNumber + ":" + x.SecondNumber) 
     .ToList(); 
} 

我們的整個功能現在只有一行,大部分代碼都是註釋。我鼓勵您瞭解並開始使用其中的一些功能;它會讓你的代碼更容易讀寫;-)

希望這有助於!

編輯:在resopnse到您的評論:

那麼將會讓他們按以下順序:2:0 1:0 0:0 2:1 1:1 0:1

它看起來像你的第二個數字排序,上升,然後由第一個數字,下降。

只需更改上面的代碼使用方法:

.OrderBy(x => x.SecondNumber) 
.ThenByDescending(x => x.FirstNumber) 
+0

明白了,謝謝! – 2011-04-03 18:05:01

+0

@casperOne - 我的錯。我會糾正這個帖子;謝謝! – Pandincus 2011-04-07 12:36:07

2

這種感覺wird,但它的工作原理根據您的要求,也許,如果你分享更多的細節的我們可以幫助更精確的解決方案,有很多假設,現在試試這個:

var sortedStrings = new ArrayList(strings.ToArray() 
    .Select(s => new { parts = ((String)s).Split(':') }) 
    .OrderByDescending(p => p.parts[0]) 
    .ThenBy(p => p.parts[1]) 
    .Select(p => String.Concat(p.parts[0], ":", p.parts[1])).ToArray()); 
+0

+1工作正常:我會改變最後一行:.Select(p => string.Format(「{0}:{1}」,p.Parts [0],p.Parts [1]))。ToArray ();並且不需要強制轉換爲字符串(至少在VS 2010中) – Marcote 2011-04-03 03:09:41

4

雖然K Ivanovright idea,這裏有一個版本,這也許是對眼睛更容易:

// Not sure what to call the "n:n" groupings. Assume 
// original is in an ArrayList named "pairs". 
IEnumerable<string> sortedPairs = 
    from pair in pairs.Cast<string>() 
    let parts = pair.Split(':') 
    let parsed = new { 
     Left = Int32.Parse(parts[0]), 
     Right = Int32.Parse(parts[1]), 
    } 
    orderby parsed.Left descending, parsed.Right 
    select pair; 

注意,對於解析像這樣,正則表達式可能是有點矯枉過正(圖案很簡單,也很清楚) 。

此外,它假設您有雙方的數字,根據您的示例。它也不會以任何方式改變字符串來返回結果。

+0

+1 - 這與我想出的非常接近。 @Mike:您可以對結果執行ToList()以獲取List 。將ArrayList替換爲其通用等價物(列表)。 – TrueWill 2011-04-03 03:20:43