【问题标题】:Sorting list of list of bytes or list of byte arrays字节列表或字节数组列表的排序列表
【发布时间】:2015-05-24 10:49:56
【问题描述】:

LINQ 与 ThenBy 等具有很好的 OrderBy 功能,但我怎样才能在 List<List<byte>> 上进行这项工作,以按第一列排序,然后按第二列等等。

字节列表列表:

[0] = {0, 1, 2, 3, 4}
[1] = {0, 0, 2, 4, 1}
[2] = {1, 2, 2, 1, 1}
[3] = {1, 0, 2, 2, 2}

实际上,当我创建 string[] 时,我只是做了同样的事情,但是将字节转换为字符串然后再转换回来很混乱,并且由于某种原因导致结果不同。

我想得到:

[0] = {0, 0, 2, 4, 1}
[1] = {0, 1, 2, 3, 4}
[2] = {1, 0, 2, 2, 2}
[3] = {1, 2, 2, 1, 1}

是否可以使用一些 LINQ 或任何其他已经制作的库来做到这一点,或者可能有任何建议如何手动制作?

【问题讨论】:

    标签: c# arrays linq sorting byte


    【解决方案1】:

    您可以从实现IComparer<IList<byte>> 开始。例如。 (为简洁省略空处理):

    public class ByteListComparer : IComparer<IList<byte>>
    {
        public int Compare(IList<byte> x, IList<byte> y)
        {
            int result;
            for(int index = 0; index<Min(x.Count, y.Count); index++)
            {
                result = x[index].CompareTo(y[index]);
                if (result != 0) return result;
            }
            return x.Count.CompareTo(y.Count);
        }
    }
    

    以上内容未经测试(甚至未编译),但应该足以让您入门。

    然后你可以在你的主列表中使用OrderBy,传入这个比较器的一个实例:

    input.OrderBy(x => x, new ByteListComparer())
    

    【讨论】:

    • 谢谢!这很好用,现在我只想找到一件事。第一个 list 是原始字节序列,排序后它位于 List> 中的某个位置。我应该浏览所有列表并检查它们是否匹配,还是有更好的理由这样做,因为有时列表可能相等?
    • @GrandaS - 如果我明白你想要什么,你可以在排序之前存储对第一个列表的引用。然后通过列表寻找匹配项。如果您特别想要第一个列表,即使有重复项,也可以使用 ReferenceEquals。或者您可以使用 ByteListComparer 来查找第一个匹配项。
    • 是的,我相信这将是我想要的引用和 ReferenceEquals。非常感谢,我去试试这个:)
    【解决方案2】:

    顺便说一句,在标记的答案中有这样一行

    for(int index = 0; index < Math.Min(x.Count, y.Count); index++)
    

    所以,函数

    Math.Min(x.Count, y.Count)
    

    将在迭代持续时被调用多次。

    必须

    int min=Math.Min(x.Count, y.Count);
    for(int index = 0; index < min; index++)
    

    【讨论】:

      【解决方案3】:

      这种方法也可以。但@Joe 展示了性能更好的方法。

      public static void Main()
      {
          List<List<Byte>> bytes = new List<List<Byte>>(){
                                              new List<Byte> {0, 1, 2, 3, 4},
                                              new List<Byte> {0, 0, 2, 4, 1},
                                              new List<Byte> {1, 2, 2, 1, 1},
                                              new List<Byte> {1, 0, 2, 2, 2}
                                      };
      
          var result = bytes.OrderBy(x => String.Join(String.Empty, x));
      
          foreach (var list in result)
          {
              foreach (var bit in list)
                  Console.Write(bit);
      
              Console.WriteLine();
          }   
      }
      

      https://dotnetfiddle.net/B8kmZX

      【讨论】:

      • 当然可以,但它会转换为字符串,我不想这样做 :) IComparer 非常适合我,Joe 建议这样做。 :)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-03-11
      • 2015-11-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多