【问题标题】:How can I sort an array returned from File.ReadAllLines on an alphabetical member?如何对按字母顺序排列的 File.ReadAllLines 返回的数组进行排序?
【发布时间】:2008-11-12 12:15:13
【问题描述】:

我正在读取一个 .csv 文件并在字符串数组中返回它的行。成员之一是制造商,我有丰田、福特等。

我想按制造商的值和字母顺序对行的数组(可以是另一个集合)进行排序。

所以我有:

28437 Ford Fiesta
328   Honda Civic
34949 Toyota Yaris

等等……

使用 C# 而没有数据库的最佳方法是什么?我说没有数据库,因为我可以将 csv 插入到 sql server 数据库中的表中,然后查询它并返回数据。但是这些数据会进入一个动态构建的 html 表中,这会使数据库方法有点冗长。

【问题讨论】:

    标签: c#


    【解决方案1】:

    您使用的是哪个版本的 .NET?如果您使用的是 3.5 - 或者可以使用 C# 3.0 和 LINQBridge - 那么我肯定会使用 LINQ。首先将每一行转换成一些合适的对象,然后使用 OrderBy:

    var cars = lines.Select(line => Car.ParseLine(line))
                    .OrderBy(car => car.Manufacturer);
    

    【讨论】:

      【解决方案2】:

      不用再猜测 Jon,我相信他是在建议您创建一个具有必要属性的 Car 类(“一些适当的对象”),并能够从一行中填充 Car:

      public class Car
      {
          public int Id {get;set;}
          public string Manufacturer {get;set;}
          public string Model {get;set;}
      
          public static Car ParseLine(string line)
          {
              string[] parts = line.Split(DELIMITER);
              return new Car
              {
                  Id = int.Parse(parts[0]),
                  Manufacturer = parts[1],
                  Model = parts[2]
              };
          }
      }
      

      即将线条视为对象。然后使用 LINQ,事情变得非常简单:

              var query = from line in lines
                          let car = Car.ParseLine(line)
                          orderby car.Manufacturer
                          select car;
      
              var arr = query.ToArray();
      

      请注意,您也可以在不使用 LINQ 的情况下执行此操作,例如(使用 Car[] 数组) - 就地数组排序:

              Array.Sort(arr, (x, y) => string.Compare(x.Manufacturer, y.Manufacturer));
      

      或与List<Car>相同:

              list.Sort((x, y) => string.Compare(x.Manufacturer, y.Manufacturer));
      

      【讨论】:

      • 请随时对我进行第二次猜测。你几乎总是要么做对,要么设法解释我没有实际上想的东西,但应该是:)
      • 你们两个应该得到 SO 的报酬 ;)
      • @David - 现在一个想法
      【解决方案3】:

      在 Jon 的帖子中,他首先将行解析为对象,然后进行排序。您也可以根据字符串的一部分对字符串的 IEnumerable 列表进行排序。这是一个在子字符串上对列表进行排序的示例(从位置 6 开始的前 10 个字符):

      List<string> lines = new List<string>
          {
              "34949 Toyota Yaris",
              "328   Honda Civic",
              "28437 Ford Fiesta"
          };
      
      var sortedLines = lines.OrderBy(line => line.Substring(6, 10));
      // Or make it case insensitive
      // var sortedLines = lines.OrderBy(line => line.Substring(6, 10), StringComparer.InvariantCultureIgnoreCase);
      
      foreach (var line in sortedLines)
      {
          Console.WriteLine(line);
      }
      

      【讨论】:

        【解决方案4】:

        如果你只有一堆字符串在一个数组中,使用

        Array.Sort(myArray)
        

        这会将字符串按字母顺序(区分大小写)放入“myArray”中。

        如果您想进行不同的比较(例如不区分大小写),您可以定义自己的 ICcomparer 或使用 Linq-Extensions,最好使用 lambda 表达式,例如

                string [] sArray = new string[] { "fsdhj", "FA", "FX", "fxx", "Äbc" };
                sArray = sArray.OrderBy(s => s.ToLowerInvariant()).ToArray();
        

        还有很多其他的排序方法,但这些是最基本的。如果我更好地理解您的输入对象的外观,我可以为您的问题提供更详细的答案。只要它只是一个字符串数组,你应该没问题。

        针对下面的前两个 cmets,我还应该注意,上面给出的不变字符串排序方法并不是该特定工作的最佳方法(请参阅 cmets)。

        但是它确实说明了如何使用带有 lambda 表达式的扩展方法,这在您没有预定义 IComparer 类的情况下非常方便。

        【讨论】:

        • 或更简单的:Array.Sort(sArray, StringComparer.InvariantCultureIgnoreCase);
        • Marc 的解决方案更正确也更简单。不应该通过首先转换为大写/小写来完成不区分大小写的排序。这在某些文化中存在问题(例如土耳其语)。
        • 对于土耳其语或其他语言的问题,我必须相信您的话。不过,它在德语中效果很好。无论如何,谢谢你的评论。我应该用一个更好的例子。
        猜你喜欢
        • 1970-01-01
        • 2015-05-17
        • 1970-01-01
        • 2017-04-12
        • 1970-01-01
        • 2010-12-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多