【问题标题】:How to sort elements of array list in C#如何在C#中对数组列表的元素进行排序
【发布时间】:2021-04-11 18:26:41
【问题描述】:

我有一个 ArrayList,其中包含,

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

现在我需要对数组列表进行排序,使其变为,

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

最后,我将从 ArrayList 中获取值并将它们用作 'int' 值。我怎样才能做到这一点?或者我应该先将它们转换为 int 然后对它们进行排序。

【问题讨论】:

  • 您使用的是什么版本的 C#?什么版本的 Visual Studio?如果您没有使用 .NET 1.1,那么您不应该使用 ArrayList。相反,您应该使用 List。在您的情况下,这看起来像 List.

标签: c#


【解决方案1】:

如果您可以确定列表只包含可以转换为整数的字符串,那么使用 IEnumerable<T>.OrderBy 扩展方法,试试这个:

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

如果您使用的是ArrayList 而不是List<string>(嘘!),您需要先使用Cast

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

您也可以定义自己的比较器,如 JaredPar 所述,但 IMO 对于已经实现的东西来说需要做很多工作。但是,它更有效。

【讨论】:

  • 这行不通。 OP 正在使用 ArrayList。你至少需要一个 .Cast
  • 而且好像需要Linq。
【解决方案2】:

框架中有许多排序方法,包括ArrayList.Sort。问题是它们都将按字母而不是数字排序。您需要编写一个理解数字排序的自定义排序器。

尝试以下方法(为简洁起见,省略了一些参数检查)

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

【讨论】:

  • 为什么还要像字符串一样比较呢?都是数字??将它们解析为 int 并返回结果是不是很容易?
  • 他会说这样做效率较低
  • @gbianchi,@Sean 是正确的。我进行 char 比较的原因是这样做比解析为数字并进行比较更有效。解析成数字效果很好,但与进行字符比较相比,它具有显着的性能差异
  • 是的,逐个字符比较字符串更有效。不过,可读性较差! ;)
  • 您说 for 和 if 调用 math.min 并重新转换为 string 比解析更快吗?我真的需要尝试一下......另外,如果你的数字更大,这仍然会更好吗?
【解决方案3】:

实现自定义比较器并将其传递给 ArrayList.Sort()

完整代码:

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

输出:

1 2 3 12 13 25

【讨论】:

  • 我认为这对于用户想要的东西来说有点复杂,但我认为它可以解决问题。
  • 它肯定会做到这一点。一旦创建了 CustomComparer,用户就可以将其作为参数添加到任何需要按数字顺序对字符串文字进行排序的地方。
【解决方案4】:

也许您可以将值存储在像 List 这样的强类型列表中,并在需要时将它们转换为字符串。像这样:

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

        intList.Sort();

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

【讨论】:

  • 附带说明,不要将其声明为 IList 否则您会被具有 Sort() 的 List 咬住,而 IList 没有。
【解决方案5】:

最好用Int 值创建另一个数组,然后用ArrayList.Sort() 对其进行排序。您可以调用 ArrayList.Sort() 并传递给它一个委托,它将这些字符串作为数字进行比较,但它会更慢。慢多少取决于你的数组的大小,我个人认为小于 100 的大小并不重要。

【讨论】:

    【解决方案6】:

    如果值都是整数,那么为什么不将它们存储为整数呢?这将使排序更容易和更快。

    这些值还有哪些其他用途?如果它们仅用作字符串并且仅排序一次,那么将它们保持原样可能是明智的 - 作为字符串。

    另一方面,如果它们用于数学运算,那么最好将它们存储为整数。

    【讨论】:

      【解决方案7】:
       List<int> liDllCnt = new List<int>();
       for (int temp = 0; temp < alFileName.Count; temp++)
           liDllCnt.Add(Int32.Parse(alFileName[temp].ToString()));
       liDllCnt.Sort();
      

      alFileName 是我使用的数组列表的名称。

      【讨论】:

      • 这是您的解决方案,那么您真的需要将数据存储为 int。
      【解决方案8】:

      这是最安全的方法

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

      结果保存到“列表”对象数组中

      【讨论】:

        【解决方案9】:

        如果您可以将 ArrayList 项放入强类型容器中,例如 List 或 String[],那么 Linq 可以轻松完成剩下的工作。以下实现仅解析字符串值一次,并使用原始字符串及其整数值为每个值创建一个匿名类型。

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

        【讨论】:

          【解决方案10】:

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2019-10-23
            • 2023-04-05
            • 2015-06-28
            • 1970-01-01
            • 1970-01-01
            • 2018-06-16
            • 2015-11-28
            相关资源
            最近更新 更多