【问题标题】:Sort List based on Array基于数组排序列表
【发布时间】:2015-04-13 07:42:24
【问题描述】:

我正在尝试根据字符串数组对自定义列表进行排序,但我失败得很惨,例如它根本没有对列表进行排序,

Public class CrateOrder
{
   public int Id { get; set; }
   public string Name { get; set; }
   public Stream OrderStream { get; set; }
}

string[] selectedFruits = {"Apple", "Mango"};  // in real get from web services
var selectedFruitsList = selectedFruits.ToList();

List<CrateOrder> cFruit = GetCrateOrderFromWebServices();

var sorted = cFruit.OrderBy(s => selectedFruitsList.IndexOf(s.Name)).ToList();

列表没有正确排序,我希望根据 selectedFruits 对 CrateOrder 列表项进行排序...

【问题讨论】:

  • 我仍然不明白您是如何尝试将您的cFruit 与您的selectedFruits 排序的。 cFruit 的输入和预期输出会有所帮助。
  • 这对我来说看起来不错 - 也许我只是错过了同样的事情,但您确定您的 cFruit 列表项实际上具有与您 selectedFruits 匹配的 Name 属性吗?
  • 这不是重复的,这里还有其他事情。
  • 我怀疑这是区分大小写的问题,IndexOf 默认会进行区分大小写的搜索,除非指定不同的规则。
  • 为我工作...dotnetfiddle.net/H1dt6p

标签: c# arrays sorting


【解决方案1】:

如果您的水果的Name 属性与您的订购列表不完全匹配,IndexOf 将始终返回 -1。要解决此问题,请指定不区分大小写的 StringComparison,但这不能作为 IndexOf 的重载,因此您必须使用稍微复杂一点的方法:

var sorted = cFruit.OrderBy(
                     s => selectedFruitsList.FindIndex(
                            x => x.Equals(s.Name, StringComparison.OrdinalIgnoreCase)) )
                  .ToList();

【讨论】:

  • 它进行了一些调整,例如OrderByDescending 并将 s.Name 转换为更低,我知道这无关紧要,但这就是它的工作原理,谢谢
  • StringComparison.OrdinalIgnoreCase 是专门必须做任何大小写转换的。
  • 我知道,但是由于某种原因,它对我不起作用,我稍后会研究它,此时太忙了:(
  • 给你:rextester.com/ZOIS35246 - 工作正常,无需更改任何内容(注意名称有一些小写首字母)
【解决方案2】:

你快到了。代码从selectedFruitsList 对水果进行排序所有其他项目之后,因为OrderBy 的顺序是升序的,并且它们是唯一返回非负数的项目。

要解决此问题,请反转 selectedFruits,并否定 IndexOf 的结果,如下所示:

string[] selectedFruits = {"Mango", "Apple"};
...
var sorted = cFruit.OrderBy(s => -selectedFruitsList.IndexOf(s.Name)).ToList();

或者,您可以扩展代码以显式处理负索引:

string[] selectedFruits = {"Apple", "Mango"};
...
var sorted = cFruit.OrderBy(s => {
    int index = selectedFruitsList.IndexOf(s.Name);
    return index < 0 ? int.MaxValue : index;
}).ToList();

【讨论】:

    【解决方案3】:

    我不知道它是否区分大小写,我可以添加忽略文化吗

    否 - Array.IndexOf 没有可让您自定义相等比较的参数。

    只需将您的所有selectedfruits 和搜索值更改为小写即可:

    string[] selectedFruits = {"Apple", "Mango"};  // in real get from web services
    var selectedFruitsList = selectedFruits.Select(s => s.ToUpperInvariant()).ToList();
    
    List<CrateOrder> cFruit = GetCrateOrderFromWebServices();
    
    var sorted = cFruit.OrderBy(s => selectedFruitsList.IndexOf(s.Name.ToUpperInvariant())).ToList;
    

    【讨论】:

    • 您至少应该使用ToLowerInvariant,但recommendation 是“在标准化字符串进行比较时使用String.ToUpperInvariant 方法而不是String.ToLowerInvariant 方法”
    • @Jamiec 很公平 - 已修改。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-15
    • 1970-01-01
    • 2013-04-02
    • 1970-01-01
    相关资源
    最近更新 更多