【问题标题】:Sort a list in C# by custom index and sameness按自定义索引和相同性对 C# 中的列表进行排序
【发布时间】:2021-06-07 09:54:50
【问题描述】:

我有一些大文件(5000+ 行项目),其中包含硬件部件的简要信息。

简单地说,每个部分都有一个 Id 和名称,文件中的所有部分都添加到 List 集合中,例如:

void Main()
{
    var parts = new List<dynamic>();

    parts.Add(make(1, "Part A"));
    parts.Add(make(2, "Part B"));
    parts.Add(make(3, "Part C"));
    parts.Add(make(4, "Part D"));
    parts.Add(make(5, "Part A"));
    parts.Add(make(6, "Part E"));
    parts.Add(make(7, "Part B"));
    parts.Add(make(8, "Part F"));
    parts.Add(make(9, "Part G"));
    parts.Add(make(10, "Part B"));
}

dynamic make(int id, string name)
{
    dynamic o = new ExpandoObject();

    o.id = id;
    o.name = name;

    return o;
}

此部件列表已排序,首先按部件 ID 的自定义排序顺序(单独确定)作为 Id 的List 提供:

var customOrderPartIds = new List<int>() { 10, 8, 6, 4, 2, 9, 7, 5, 3, 1 };

parts.OrderBy(p => customOrderPartIds.IndexOf(p.id)).ToList();
/*
This gives the needed order:

10 - Part B
8 - Part F
6 - Part E
4 - Part D
2 - Part B
9 - Part G
7 - Part B
5 - Part A
3 - Part C
1 - Part A
*/

现在,我需要的第二个顺序是相同的零件名称放在一起,但保持第一个顺序不变,以及零件组增量编号:

/*
This is the needed final order, along with an increment:

10 - Part B - 1
2 - Part B - 1
7 - Part B - 1
8 - Part F - 2
6 - Part E - 3
4 - Part D - 4
9 - Part G - 5
5 - Part A - 6
1 - Part A - 6
3 - Part C - 7
*/

如何做到这一点?

【问题讨论】:

  • 这能回答你的问题吗? LINQ OrderBy with more than one field
  • 您可以使用 OrderBy(e => e.Property).ThenBy(e => e.OtherProperty) 进行链式排序
  • 谢谢。不幸的是,它没有帮助。如果我使用ThenBy 并执行parts.OrderBy(p =&gt; customOrderPartIds.IndexOf(p.id)).ThenBy(p =&gt; p.name).ToList(); 之类的操作,则结果不会反映我需要的第二次排序(上面的示例输出)。
  • 为什么要使用dynamic 而不是具有IdName 属性的类?即使是ValueTuple&lt;int, id&gt; 也比动态的要好得多。
  • @Nick:不要使用动态来简化你的问题,那样会引发与你的问题无关的其他问题。

标签: c#


【解决方案1】:

你可以把它分组,然后再次输出。

var result = parts.OrderBy(p => customOrderPartIds.IndexOf(p.id))
             .GroupBy(x => x.name)
             .SelectMany(x => x);

【讨论】:

  • 缺少增量编号,但添加起来很简单
【解决方案2】:

类似的事情应该作为第二次订购:

parts = parts.SelectMany(
    item => parts.First(p => p.Name == item.Name) == item ? 
        parts.Where(p => p.Name == item.Name) : new List<dynamic>()).ToList();

如果是该组的第一个:返回该组的所有项目。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-03-23
    • 2022-01-08
    • 2011-03-16
    • 2013-05-06
    • 2015-07-04
    • 1970-01-01
    • 2016-09-10
    相关资源
    最近更新 更多