列表基于另一个列表排序

dan*_*son 27 c# linq sorting

我有两个通用的列表对象,其中一个包含id和排序,另一个是一堆id,第二个列表中的每个id都有一个id引用第一个列表,例如;

public class OptionType
{
    public int ID { get; set; }
    public int Ordering { get; set; }
}

public class Option
{
    public int ID { get; set; }
    public int Type_ID { get; set; }
}   
Run Code Online (Sandbox Code Playgroud)

显然,我可以通过这样做对OptionTypes列表进行简单的排序

types_list.OrderBy(x => x.Ordering);
Run Code Online (Sandbox Code Playgroud)

问题是,我怎么能通过利用对象上的'Type_ID'来排序'options_list',这与types_list的排序有关.就像在某种类似的东西(显然这是无效的 - 但希望你会得到这个想法!)

options_list.OrderBy(x => x.Type_ID == types_list.OrderBy(e => e.Ordering));
Run Code Online (Sandbox Code Playgroud)

Ant*_*ram 35

您应该能够使用连接来生成所需的输出.使用查询语法的示例.

var orderedOptions = from option in options_list
                     join type in types_list
                     on option.Type_ID equals type.ID
                     orderby type.Ordering
                     select option;
Run Code Online (Sandbox Code Playgroud)


Goo*_*ide 17

如果您使用小型列表,List.FindIndex()是您的朋友:

var orderedB = listB.OrderBy(b => listA.FindIndex(a => a.id == b.id));
Run Code Online (Sandbox Code Playgroud)

工作示例:https://dotnetfiddle.net/CpLeFU

正如MaxJ在评论中指出的那样,性能将成为大型列表的噩梦.在这种情况下使用接受的答案.

  • 这比连接简单得多.假设listA已按所需顺序排序(type.Ordering).也就是说,它使用listA在列表中的位置,而不是listA的属性.它也在执行多个FindIndex,因此可能在大型列表上存在性能问题. (2认同)

goo*_*eye 9

我喜欢Lambda语法,所以我提出了这个等价物.我可以看到查询语法如何更清晰的连接.

var orderedOptions = options_list
    .Join(
        types_list,
        option => option.Type_ID,
        type => type.ID,
        (option, type) => new { Option = option, Type = type })
    .OrderBy(x => x.Type.Ordering)
    .Select(x => x.Option);
Run Code Online (Sandbox Code Playgroud)



为了略微减少(我不确定),这将仅使用Ordering属性创建新对象,而不是整个Type类.这里没什么不同,但是我有一个包含排序数据的大类,只需要sort属性.不知道它是否重要,但阅读更清楚.

var orderedOptions = options_list
    .Join(
        types_list,
        option => option.Type_ID,
        type => type.ID,
        (option, type) => new { Option = option, Ordering = type.Ordering })
    .OrderBy(x => x.Ordering)
    .Select(x => x.Option);
Run Code Online (Sandbox Code Playgroud)

看起来查询语法允许您在初始查询中进行排序,而lambda在连接创建新对象后需要排序.也许他们在封面下真的做了同样的事情:创建连接对象,然后进行排序然后选择.