简体   繁体   English

如何在C#中对数组列表的元素进行排序

[英]How to sort elements of array list in C#

I have an ArrayList that contains,我有一个 ArrayList 包含,

[0] = "1"
[1] = "10"
[2] = "2"
[3] = "15"
[4] = "17"
[5] = "5"
[6] = "6"
[7] = "27"
[8] = "8"
[9] = "9"

Now i need to sort the array list such that it becomes,现在我需要对数组列表进行排序,使其变为,

[0] = "1"
[1] = "2"
[2] = "5"
[3] = "6"
[4] = "8"
[5] = "9"
[6] = "10"
[7] = "15"
[8] = "17"
[9] = "27"

At last i will be getting the values from ArrayList and using them as 'int' values.最后,我将从 ArrayList 获取值并将它们用作“int”值。 How can i do this?我怎样才能做到这一点? Or shall i convert them to int at first and then sort them.?或者我应该首先将它们转换为 int 然后对它们进行排序。?

If you can be sure the list contains only strings that can be transformed to integers, then with the IEnumerable<T>.OrderBy extension method, try this:如果您可以确定列表只包含可以转换为整数的字符串,那么使用IEnumerable<T>.OrderBy扩展方法,试试这个:

var sortedList = list.OrderBy(item => int.Parse(item));

If you're using an ArrayList instead of a List<string> (boo!), you'll need to Cast first:如果您使用的是ArrayList而不是List<string> (嘘!),您需要先进行Cast

var sortedList = list.Cast<string>().OrderBy(item => int.Parse(item));

You can also define your own comparer as JaredPar noted, but IMO that's a lot of work for something that's already implemented.您也可以像 JaredPar 所说的那样定义自己的比较器,但是 IMO 对于已经实现的东西来说需要做很多工作。 However, it's more efficient.但是,它更有效。

There are numerous sort methods in the framework including ArrayList.Sort.框架中有许多排序方法,包括 ArrayList.Sort。 The problem is that they are all going to sort alphabetically and not numerically.问题是它们都将按字母顺序而不是数字顺序排序。 You'll need to write a custom sorter that understands numeric sorts.您需要编写一个理解数字排序的自定义排序器。

Try the following (some argument checking left out for brevity)尝试以下操作(为简洁起见,省略了一些参数检查)

public class NumericComparer : IComparer {
  public int Compare(object x, object y) {
    string left = (string)x; 
    string right = (string)y;
    int max = Math.Min(left.Length, right.Length);
    for ( int i = 0; i < max; i++ ) {
      if ( left[i] != right[i] ) { 
        return left[i] - right[i];
      }
    }
    return left.Length - right.Length;
  }
}

list.Sort(new NumericComparer());

Implement custom comparer and pass it to ArrayList.Sort()实现自定义比较器并将其传递给 ArrayList.Sort()

Complete Code:完整代码:

using System;
using System.Collections;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            ArrayList a = new ArrayList();
            a.Add("1");
            a.Add("13");
            a.Add("3");
            a.Add("25");
            a.Add("2");
            a.Add("12");
            a.Sort(new CustomComparer());

            foreach (String s in a)
                Console.WriteLine(s);

            Console.Read();
        }


    }

    public class CustomComparer : IComparer
    {
        Comparer _comparer = new Comparer(System.Globalization.CultureInfo.CurrentCulture);

        public int Compare(object x, object y)
        {
            // Convert string comparisons to int
            return _comparer.Compare(Convert.ToInt32(x), Convert.ToInt32(y));
        }
    }
}

Output:输出:

1 2 3 12 13 25 1 2 3 12 13 25

Maybe you could store the values in a strongly typed list like List instead, and the, if necessary, convert them to string, when cosuming them.也许您可以将这些值存储在像 List 这样的强类型列表中,如果需要,在使用它们时将它们转换为字符串。 Like this:像这样:

        List<int> intList = new List<int>(new int[] {3, 2, 1});

        intList.Sort();

        foreach (int theInt in intList)
        {
            System.Diagnostics.Debug.WriteLine(theInt.ToString());
        }

You'll be better of creating another array with Int values and then sorting it with ArrayList.Sort() .您最好使用Int值创建另一个数组,然后使用ArrayList.Sort()对其进行排序。 You could call ArrayList.Sort() and pass it a delegate that will compare those strings as numbers but it will be slower.您可以调用ArrayList.Sort()并向其传递一个委托,该委托会将这些字符串作为数字进行比较,但速度会更慢。 How much slower depends on size of your array and I personally think for sizes less then 100 it doesn't really matter.慢多少取决于数组的大小,我个人认为对于小于 100 的大小并不重要。

Arraylist Sort(CaseSensitive) in Ascending Order Helpful for someone按升序排列的 Arraylist Sort(CaseSensitive) 对某人有帮助

class ArrayCaseSensitive:IComparer
    {
        int IComparer.Compare(object x, object y)
        {
            return (new CaseInsensitiveComparer().Compare(x,y));
        }

    public static void Main(string[] args)
    {
            IComparer sc = new ArrayCaseSensitive();
           
        ArrayList arr = new ArrayList();
        arr.Add("AB");
        arr.Add("bc");
        arr.Add("1");
        arr.Sort(sc);
        foreach(var strs in arr)
        {
            Console.WriteLine(strs);
        }
        
    }

}

If the values are all ints then why not store them as ints?如果值都是整数,那么为什么不将它们存储为整数呢? That would make sorting easier and faster.这将使排序更容易和更快。

In what other ways are the values used?这些值还以其他哪些方式使用? If they're only used as strings and only sorted once then it's probably sensible to leave them as they are - as strings.如果它们仅用作字符串并且仅排序一次,那么将它们保持原样可能是明智的 - 作为字符串。

On the other hand, if they're used in maths ops then it's best to store them as ints.另一方面,如果它们用于数学运算,那么最好将它们存储为整数。

 List<int> liDllCnt = new List<int>();
 for (int temp = 0; temp < alFileName.Count; temp++)
     liDllCnt.Add(Int32.Parse(alFileName[temp].ToString()));
 liDllCnt.Sort();

alFileName is the name of the arraylist that i used. alFileName 是我使用的数组列表的名称。

This is the safest way这是最安全的方式

aryList is your ArrayList instance aryList 是你的 ArrayList 实例

                object[] list = aryList.ToArray();
                Array.Sort<object>
                    (
                        list,
                        delegate(object x, object y)
                        {
                            int a = 0, b = 0;
                            if (x == y) return 0;
                            if (x == null || y == null)
                                return x == null ? -1 : 1;
                            int.TryParse(x.ToString(), out a);
                            int.TryParse(y.ToString(), out b);
                            return a.CompareTo(b);
                        }
                    );

result saved into "list" object array结果保存到“列表”对象数组中

If you can get the ArrayList items into a strongly typed container such as List<String> or String[] then Linq makes it easy to do the rest.如果您可以将 ArrayList 项放入强类型容器(例如 List<String> 或 String[])中,则 Linq 可以轻松完成其余工作。 The following implementation parses the string values only once and creates an anonymous type for each with the original string and its integer value.以下实现仅解析字符串值一次,并使用原始字符串及其整数值为每个值创建一个匿名类型。

public void Test_SortArrayList()
{
    ArrayList items = new ArrayList(new []{"1", "10", "2", "15", "17", "5", "6", "27", "8", "9"});
    string[] strings = (string[])items.ToArray(typeof(string));
    List<string> result = strings
        .Select(x => new
            {
                Original = x,
                Value = Int32.Parse(x)
            })
        .OrderBy(x => x.Value)
        .Select(x => x.Original)
        .ToList();
    result.ForEach(Console.WriteLine);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM