C# - 对字符串的 ArrayList 进行排序 [英] C# - Sorting an ArrayList of strings

查看:21
本文介绍了C# - 对字符串的 ArrayList 进行排序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个如下所示的 ArrayList 字符串,我想输出一个以特定方式排序的新 ArrayList.但不确定排序的好方法.将非常感谢帮助!

I have an ArrayList of strings that look as below, I would like to output a new ArrayList sorted in a particular way. But not sure of a good way of sorting it. Help will be really appreciated!

原始(可以是任何随机顺序):

Original (can be in any random order):

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.让我们一步一步来.

While I think both of the other answers are spot-on, I'm going to assume you're unfamiliar with some of the features of .NET 2.0 and .NET 3.5 they used. Let's take it one step at a time.

所以你得到了一个 ArrayList,其中包含以下数据:

So you're given an ArrayList holding the following data:

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

首先,使用RegEx没有错;也许是轻微的性能损失.如果字符串真的像这样简单,你可以使用Split:

First of all, nothing is wrong with using RegEx; perhaps a minor performance penalty. If the strings are really as simple as this, you can just use 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.

However, since you said you're using .NET 4, you really shouldn't be using ArrayList at all -- note that it requires you to cast your values to their appropriate type, e.g. string mystring = myArray[i] as string.

有很多很棒的功能您没有利用,例如泛型(在 .NET Framework 中,因为 2.0).让我们编写一个函数,它给定一个 ArrayList,但返回一个排序的通用 List(一个只包含字符串的列表).一起来看看:

There are plenty of great features you're not taking advantage of, such as generics (in the .NET Framework since 2.0). Let's write a function that is given an ArrayList, but returns a sorted generic List<string> (a list that only holds strings). Let's have a look:

/// <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 等.非常烦人!

Now, the above code works, but is really long. Note that you have to create a class just to hold these two values, make that class implement IComparable, etc, etc. Pretty annoying!

.NET 3.5 推出了一些很棒的功能,包括匿名类型LINQ.让我们更改代码以使用这两个功能.

.NET 3.5 came out with some great features, including anonymous types and LINQ. Let's change our code to use both of those features.

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

我们的整个函数现在只有一行,大部分代码都是注释.我鼓励您了解并开始使用其中的一些功能;它会让你的代码更容易阅读和编写;-)

Our entire function is just one line now, and most of the code is comments. I encourage you to learn about and start using some of these features; it'll make your code a lot easier to read and write ;-)

希望这有帮助!

根据您的评论:

将它们按以下顺序排列需要什么:2:0 1:0 0:0 2:1 1:1 0:1

What would it take to have them in the following order: 2:0 1:0 0:0 2:1 1:1 0:1

看起来您是按第二个数字升序排序,然后按第一个数字降序排序.

It looks like you're sorting by the second number, ascending, and then by the first number, descending.

只需更改上面的代码即可使用:

Simply change the code above to use:

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

这篇关于C# - 对字符串的 ArrayList 进行排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆