【问题标题】:Is it possible to use an array with the OrderBy method?是否可以通过 OrderBy 方法使用数组?
【发布时间】:2021-01-14 15:36:01
【问题描述】:

我想通过 SQL 查询对表中的 var 'StorageLocation' 进行排序,并按定义的数组对其进行排序。

我的数组:string[] sortedLocations = {"Location A", "Location B", "Location 2"};

我尝试了什么:reportRecords.OrderBy(o => o.StorageLocation == sortedLocations[o])

此代码当前具有所需的结果。它将按我首先设置的 StorageLocations 进行排序,然后将其余部分附加到末尾。当我更改/重新排序 StorageLocation 时,这有点乏味。

public void ActiveReport_ReportStart()
{
    // Create report query and set the report datasource
    using (var context = sqlDB.CreateContext())
    {
        var reportRecords = (from ii in context.IssuedItems
                                where (ii.Item.BarcodeId.Length == 9)
                                select new
                                {
                                    ii.Item.StorageLocation,
                                    ii.Item.BarcodeId,
                                    ii.User.UsernameId
                                }).ToList();
        reportRecords = reportRecords.OrderBy(o =>
            // Order by defined StorageLocation first
            o.StorageLocation == "Location A" ? 1 :
            o.StorageLocation == "Location B" ? 2 :
            o.StorageLocation == "Location 2" ? 3 : 4
            ).ThenBy(o => o.BarcodeId).ToList();
        rpt.DataSource = reportRecords;
    }
}

非常感谢任何帮助! :)

这样会更有效吗?

List<reportRecords> definedLocations = new List<reportRecords>() 
{
    "Location A",
    "Location B",
    "Location 2"
};

List<reportRecords> sorted = (from e in definedLocations
    orderby e.BarcodeId
    select e).ToList();

【问题讨论】:

  • 您可以将其设为Dictionary&lt;string, int&gt; { [1] = "Location A", [2] = ...},然后将其设为OrderBy(o =&gt; sortedLocations.GetValueOrDefault(o.StorageLocation, 4))
  • @juharr 谢谢你的回复。我试图摆脱数组中的索引号,只是根据第一个元素对其进行排序。我在 SQL 数据库中有很多位置,我可能需要修改数组以在“位置 A”之前出现不同的位置,所以我想轻松地将其添加到顶部。我编辑了这篇文章,希望有一个更清晰的例子。

标签: c# arrays sorting


【解决方案1】:

您可以将 IComparer 的实现作为第二个参数传递给 OrderBy。然后在该比较器中,您可以添加逻辑以使用您的数组作为比较。

注意:我相信你可以让我的“左/右”更有效率,但它确实有效。我这样做是为了将未找到的元素放在最后。您还可以回退到对不在列表中的元素进行常规字符串比较后知道它们之后。

static void Main(string[] args)
{
    var mylist = new List<string> { "Location 2", "Location A", "Location B", "Location X" };
    mylist = mylist.OrderBy(t => t, new MyComparer()).ToList();
    Console.WriteLine(string.Join(", ", mylist));
}

class MyComparer : IComparer<string>
{
    List<string> MyOrder = new List<string> { "Location A", "Location 2", "Location B" };

    public int Compare(string x, string y)
    {
        var left = MyOrder.IndexOf(x) == -1 ? int.MaxValue : MyOrder.IndexOf(x);
        var right = MyOrder.IndexOf(y) == -1 ? int.MaxValue : MyOrder.IndexOf(y);
        return left - right;
    }
}

【讨论】:

    【解决方案2】:

    我找到了解决问题的方法:

    // create array for locations to order reportRecords by
    String[] definedLocations = {
        "Location A", 
        "Location B", 
        "Location 2"
    };
    
    // create a table then add the array definedLocations
    var sortedLocations = new List<String>();
    sortedLocations.AddRange(definedLocations);
    

    ~

    // IndexOf is used to match strings in sortedLocations with StorageLocations
    reportRecords = reportRecords.OrderBy(o => sortedLocations.IndexOf(o.StorageLocation)).ToList();
    

    在我的情况下,唯一的不良影响是definedLocations 中未列出的任何位置都位于列表顶部。因此,如果StorageLocation 具有“位置 Y”,它将位于“位置 A”之前。

    这将是另一天的战斗。感谢那些评论的人。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-06
      • 2014-11-14
      • 2018-05-21
      • 1970-01-01
      • 1970-01-01
      • 2011-06-08
      相关资源
      最近更新 更多