我有一个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
我有一个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
虽然我认为其他答案都是现成的,但我会假设您不熟悉他们使用的.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)
明白了,谢谢! – 2011-04-03 18:05:01
@casperOne - 我的错。我会纠正这个帖子;谢谢! – Pandincus 2011-04-07 12:36:07
这种感觉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());
+1工作正常:我会改变最后一行:.Select(p => string.Format(“{0}:{1}”,p.Parts [0],p.Parts [1]))。ToArray ();并且不需要强制转换为字符串(至少在VS 2010中) – Marcote 2011-04-03 03:09:41
虽然K Ivanov有right 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;
注意,对于解析像这样,正则表达式可能是有点矫枉过正(图案很简单,也很清楚) 。
此外,它假设您有双方的数字,根据您的示例。它也不会以任何方式改变字符串来返回结果。
+1 - 这与我想出的非常接近。 @Mike:您可以对结果执行ToList()以获取List
@Mike - 有没有可能来存储信息的对象,而不是字符串?即他们需要是字符串,还是只有当他们输出? – Pandincus 2011-04-03 02:50:39
@Pandincus:我想再次输出它们作为排序的字符串。但是,如果这使得它更容易,我想这会很好。 – 2011-04-03 02:53:40
@Mike - 另外,你使用的是什么版本的.NET Framework? – Pandincus 2011-04-03 02:56:21