代码之家  ›  专栏  ›  技术社区  ›  dan richardson

基于另一个列表的列表排序

  •  27
  • dan richardson  · 技术社区  · 14 年前

    我有两个通用的list对象,其中一个包含id和ordering,另一个是一堆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; }
    }   
    

    显然,我可以通过

    types_list.OrderBy(x => x.Ordering);
    

    但问题是,如何利用对象上的“Type\u ID”来对“options\u list”进行排序,这与类型\u list的排序有关。就像这样(显然这是无效的-但希望你能得到这个想法!)

    options_list.OrderBy(x => x.Type_ID == types_list.OrderBy(e => e.Ordering));
    
    3 回复  |  直到 8 年前
        1
  •  39
  •   Anthony Pegram    11 年前

    var orderedOptions = from option in options_list
                         join type in types_list
                         on option.Type_ID equals type.ID
                         orderby type.Ordering
                         select option;
    
        2
  •  26
  •   Good Night Nerd Pride    4 年前

    List.FindIndex() 当你处理小列表时,你是你的朋友:

    var orderedB = listB.OrderBy(b => listA.FindIndex(a => a.id == b.id));
    

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

    正如@goodeye在评论中指出的,在更大的列表中,性能将是一场噩梦。使用 accepted answer 那样的话。

        3
  •  9
  •   goodeye    10 年前

    我喜欢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);
    



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

    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);
    

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