我有一个ArrayList
字符串,如下所示,我想输出一个以特定方式排序的新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 :(得分:4)
虽然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 :(得分:2)
这感觉很奇怪,但它的工作原理基于您的要求,也许如果您分享更多我们可以提供更多精确解决方案的细节,那么有许多假设,现在试试这个:
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());
答案 2 :(得分:1)
虽然我认为其他两个答案都是正确的,但我会假设你不熟悉他们使用的.NET 2.0和.NET 3.5的一些功能。让我们一步一步。
因此,您获得了ArrayList
,其中包含以下数据:
{ "1:1", "0:0", "0:1", "2:1", "1:0", "2:0" }
首先,使用RegEx没有任何问题;也许是轻微的性能损失。如果字符串真的如此简单,您可以使用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
。
有很多很棒的功能,你没有利用它们,比如泛型(自2.0以来的.NET Framework)。让我们编写一个给定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();
}
我们的整个功能现在只有一行,大部分代码都是注释。我鼓励您了解并开始使用其中的一些功能;它会使你的代码更容易阅读和写作; - )
希望这有帮助!
编辑:依旧评论:
按以下顺序排列它们需要什么:
2:0 1:0 0:0 2:1 1:1 0:1
看起来你按第二个数字排序,升序,然后按第一个数字排序,降序。
只需更改上面的代码即可使用:
.OrderBy(x => x.SecondNumber)
.ThenByDescending(x => x.FirstNumber)