简体   繁体   English

Linq查询到orderby级别然后是父项和子项

[英]Linq query to orderby level then parent and child item

I have looked up some orderby examples but I'm still confused about the best linq expression to sort the assembly in the code to produce this list: 我查了一些有序的例子,但我仍然对最好的linq表达式感到困惑,要在代码中对程序集进行排序以生成这个列表:

Level Parent      Child  
1     L010057501U 231-100-002  
1     L010057501U 307-355-022  
2     307-355-022 307-355-058  
3     307-355-058 355-100-008  
3     307-355-058 357-200-002  
2     307-355-022 307-355-059  
3     307-355-059 355-200-005  
3     307-355-059 357-100-002  

The results needs to be sorted by level but the child needs to be immediately after the parent before the next parent is listed. 结果需要按级别排序,但子项需要紧跟在父级之后才能列出下一个父级。 The components of the assembly could be several levels deep. 装配的组件可以是几层深。 I hope I have explained adequately. 我希望我已经充分解释了。

    class Program
{
    static void Main(string[] args)
    {
        SortAssembly();
        Console.ReadLine();
    }
    class Assembly
    {
        public int Level { get; set; }
        public string Parent { get; set; }
        public string Component { get; set; }
    }

    private static void SortAssembly()
    {
        Assembly[] assemblies = { 
            new Assembly { Level=1, Parent="L010057501U", Component="231-100-002" },
            new Assembly { Level=1, Parent="L010057501U", Component="307-355-022" },
            new Assembly { Level=2, Parent="307-355-022", Component="307-355-058" },
            new Assembly { Level=2, Parent="307-355-022", Component="307-355-059" },
            new Assembly { Level=3, Parent="307-355-058", Component="355-100-008" },
            new Assembly { Level=3, Parent="307-355-059", Component="355-200-005" },
            new Assembly { Level=3, Parent="307-355-059", Component="357-100-002" },
            new Assembly { Level=3, Parent="307-355-058", Component="357-200-002" }
        };

        var query = ???  

        foreach (var part in query)
        {
            Console.WriteLine("{0} - {1} - {2}", part.Level, part.Parent, part.Component);
        }
    }
}

1 - L010057501U - 231-100-002 1 - L010057501U - 231-100-002
1 - L010057501U - 307-355-022 1 - L010057501U - 307-355-022
____2 - 307-355-022 - 307-355-058 ____2 - 307-355-022 - 307-355-058
________3 - 307-355-058 - 355-100-008 ________3 - 307-355-058 - 355-100-008
________3 - 307-355-058 - 357-200-002 ________3 - 307-355-058 - 357-200-002
____2 - 307-355-022 - 307-355-059 ____2 - 307-355-022 - 307-355-059
________3 - 307-355-059 - 355-200-005 ________3 - 307-355-059 - 355-200-005
________3 - 307-355-059 - 357-100-002 ________3 - 307-355-059 - 357-100-002

I tried to implement the IComparable but I'm not grasping it. 我试图实现IComparable但我没有抓住它。 Still need help on this. 仍然需要帮助。

you can try the following 你可以试试以下

using System;
using System.Linq;


    public class Assembly
    {
        public int Level { get; set; }
        public string Parent { get; set; }
        public string Component { get; set; }
        public bool Visited{get;set;} // to track visited levels
    }
public class Program
{
    public static void Main()
    {
                Assembly[] assemblies = { 
            new Assembly { Level=1, Parent="L010057501U", Component="231-100-002" },
            new Assembly { Level=1, Parent="L010057501U", Component="307-355-022" },
            new Assembly { Level=2, Parent="307-355-022", Component="307-355-058" },
            new Assembly { Level=2, Parent="307-355-022", Component="307-355-059" },
            new Assembly { Level=3, Parent="307-355-058", Component="355-100-008" },
            new Assembly { Level=3, Parent="307-355-059", Component="355-200-005" },
            new Assembly { Level=3, Parent="307-355-059", Component="357-100-002" },
            new Assembly { Level=3, Parent="307-355-058", Component="357-200-002" }
        };
        DisplayAssemblies(assemblies);

    }

    private static void DisplayAssemblies(Assembly[] data)
    {
        // order the data to be sorted by levels
        var levels=data.OrderBy(t=>t.Level);
        foreach(var level in levels)
            if(!level.Visited)
                DisplayLevel(level,data);

    }

    private static void DisplayLevel(Assembly level, Assembly[] data)
    {
        var childs=data.Where(t=>t.Parent==level.Component).ToArray();
        Console.WriteLine("{0} - {1} - {2}", level.Level, level.Parent, level.Component);
        level.Visited=true;
        foreach(var child in childs)
        {       
            DisplayLevel(child,data);
        }
    }
}

OUTPUT: OUTPUT:


1 - L010057501U - 231-100-002
1 - L010057501U - 307-355-022
2 - 307-355-022 - 307-355-058
3 - 307-355-058 - 355-100-008
3 - 307-355-058 - 357-200-002
2 - 307-355-022 - 307-355-059
3 - 307-355-059 - 355-200-005
3 - 307-355-059 - 357-100-002

here a Live DEMO 这是一个现场演示

hope this will help you 希望这个能对您有所帮助

Have your Assembly class implement IComparable which allows you to define how they are ordered by implementing its only method: CompareTo() 让您的Assembly类实现IComparable ,它允许您通过实现其唯一的方法来定义它们的排序方式: CompareTo()

I THINK you were saying that you need to order first by Level, then Parent, then Component. 我认为你说你需要先按Level,然后是Parent,然后是Component。 If so you could use something like this: 如果是这样,你可以使用这样的东西:

class Assembly:IComparable
{
    public int Level { get; set; }
    public string Parent { get; set; }
    public string Component { get; set; }

    public int CompareTo(object obj)
    {
        var other = obj as Assembly;

        if (this.Level != other.Level)
        {
            return this.Level.CompareTo(other.Level);
        }

        if (this.Parent != other.Parent)
        {
            return this.Parent.CompareTo(other.Parent);
        }

        return this.Component.CompareTo(other.Component);
    }
}

But, if I have misunderstood your logic, then the idea is to have CompareTo() return a positive integer if this comes before other and a negative integer if other comes before this (or 0 if they are of equal rank). 但是,如果我误解你的逻辑,那么这个想法是具有CompareTo()返回一个正整数,如果this到来之前other若是否定整数other来之前, this (或0 ,如果他们是同等级别的)。

Once you have IComparable implemented you can just do: 一旦实施了IComparable您就可以:

query = assemblies.OrderBy(a => a);

in order to sort the Assemly objects by your own custom ordering 为了按照自己的自定义顺序对Assemly对象进行排序

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM