【问题标题】:Sorting list of strings using linq with custom sort使用带有自定义排序的 linq 对字符串列表进行排序
【发布时间】:2017-02-22 21:33:47
【问题描述】:

我正在尝试按照与常见修订历史序列中使用的序列相关的顺序对字符串列表进行排序。一些客户以“-”或“New”或其他一些特定代码开头,我可以使用 LINQ 定义自定义排序顺序。但是,在图纸从 Rev A 一直修改到 Rev Z 之后,它变成 Rev AA 到 Rev AZ,然后是 Rev BA 到 BZ,以此类推。如何使用 LINQ 对以下列表进行排序?

我有这个作为示例代码块:

List<string> revList = new List<string>  { "A", "NC", "New", "AB", "PD", "PD1", 
                                          "PD2", "B", "-", "*", "BB", "NA" };
revList = revList.OrderByDescending(i => i.ToLower() == "pd").
                  ThenByDescending(i => i.ToLower() == "nc").
                  ThenByDescending(i => i.ToLower() == "na").
                  ThenByDescending(i => i.ToLower() == "new").
                  ThenByDescending(i => i.ToLower() == "pd1").
                  ThenByDescending(i => i.ToLower() == "pd2").
                  ThenByDescending(i => i.ToLower() == "-").
                  ThenByDescending(i => i.ToLower() == "*").
                  ThenBy(i => i).ToList();

foreach (string rev in revList)
  Console.WriteLine(rev);

这会产生如下输出:

PD
NC
NA
NEW
PD1
PD2
-
*
A
AB
B
B

我想制作:

PD
NC
NA
NEW
PD1
PD2
-
*
A
B
AB
BB

【问题讨论】:

  • 首先按Length排序,例如在ThenBy(i =&gt; i)之前插入ThenBy(i =&gt; i.Length).
  • 伊万,你赢了。我希望我能投票给你的答案,因为它是第一个,但这是一个评论。谢谢。
  • 为什么PD 出现在NC 之前是想要的结果?
  • @JonathanWood 因为第一条规则本身!
  • @JonathanWood 仅与我们的特定编号要求相关的晦涩细节。相关的部分是我可以使用 LINQ 创建一个特定的顺序序列,但我不知道如何让后续序列以非字母顺序工作。

标签: c# linq sorting


【解决方案1】:

这段代码对我有用。

 var revList = new List<string>  { "A", "NC", "New", "AB", "PD", "PD1",
                                      "PD2", "B", "-", "*", "BB", "NA" };

        revList = revList.OrderByDescending(i => i.ToLower() == "pd").
                          ThenByDescending(i => i.ToLower() == "nc").
                          ThenByDescending(i => i.ToLower() == "na").
                          ThenByDescending(i => i.ToLower() == "new").
                          ThenByDescending(i => i.ToLower() == "pd1").
                          ThenByDescending(i => i.ToLower() == "pd2").
                          ThenByDescending(i => i.ToLower() == "-").
                          ThenByDescending(i => i.ToLower() == "*").
                          ThenBy(i => i.Length).ToList();

        foreach (string rev in revList)
            Console.WriteLine(rev);
        Console.ReadLine();

【讨论】:

  • 谢谢,萨米尔!我不敢相信我没有想到这一点。
【解决方案2】:

你可以像这样创建一个自定义对象:

class Revision
{
    public string Name { get; set; }
    public int Rank { get; set; }

    public Revision(string Name, int Rank)
    {
        this.Name = Name;
        this.Rank = Rank;
    }
}

然后您可以创建这些对象的列表。

类似:

List<Revision> revisions = new List<Revision>();
revision.Add(new Revision("PD",1));
revision.Add(new Revision("NC",2));

现在您可以使用 LINQ 按排名进行排序,而不是尝试解析名称。

最初设置对象可能会很痛苦,因为您可能需要前往 ZZ,但这会让您完全控制订单。

附言- 我没有测试这段代码。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-05-08
    • 1970-01-01
    • 1970-01-01
    • 2012-04-22
    • 1970-01-01
    • 1970-01-01
    • 2010-11-29
    • 2015-03-26
    相关资源
    最近更新 更多