Linq 查询到按顺序级别,然后是父项和子项

本文关键字:然后 查询 顺序 Linq | 更新日期: 2023-09-27 18:30:39

我已经查找了一些按顺序排列的示例,但我仍然对在代码中对程序集进行排序以生成此列表的最佳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  

结果需要按级别排序,但子项需要紧跟在父项之后,然后才能列出下一个父项。 组件的组件可以有多个级别深。 我希望我已经充分解释了。

    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

我试图实现IComparable,但我没有掌握它。 仍然需要帮助。

Linq 查询到按顺序级别,然后是父项和子项

您可以尝试以下操作

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

输出:


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

这是一个现场演示

希望这对你有帮助

让你的Assembly类实现IComparable,这允许你通过实现它的唯一方法来定义它们的排序方式:CompareTo()

我想你是说你需要首先按级别排序,然后按父级排序,然后按组件排序。如果是这样,您可以使用这样的东西:

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

但是,如果我误解了你的逻辑,那么这个想法是让CompareTo()返回一个正整数,如果thisother之前,otherthis之前返回一个负整数(如果它们排名相同,则返回0)。

一旦你实现了IComparable,你就可以做:

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

为了按您自己的自定义顺序对Assemly对象进行排序