Linq query on orderby level then parent and child

I've looked at some ordering examples, but I'm still confused about the best linq expression for sorting an assembly in the code to create this list:

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 must be sorted by level, but the child must be immediately after the parent before the next parent is listed. Assembly components can be on multiple levels. I hope I have explained this properly.

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

I tried to implement IComparable, but I don't understand it. Still need help with this.

+3


source to share


2 answers


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:




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 is Live DEMO

hope this helps you

+2


source


Ask to implement a Assembly

class Assembly

that allows you to define how they are ordered by implementing its single method:CompareTo()

I THINK you said that you need to order first by level, then by parent, then by component. If so, you can 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 misunderstood your logic, then the idea is to CompareTo()

return a positive integer if this

preceded other

and a negative integer if other

preceded this

(or 0

if they are of equal rank).



Once you are done IComparable

, you can simply do:

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

      

to sort objects Assemly

by your own order

0


source







All Articles