如何在列表中首先对具有父对象的潜在父项的列表进行排序?

时间:2015-07-29 05:10:45

标签: c# list sorting

在C#中,如果我有一个对象列表,其中每个对象可以有一个父对象,并且每个父对象都可以有一个父对象(x组合),那么对列表进行排序的最佳方法是如何使所有父对象都是列表中的第一个?

这是对象结构:

class test
{
    int id { get; set; }
    int parentId { get; set; }
    bool hasParentObject { get; set; }
}

以下是一些对象的示例:

对象a:

id = 1;
parentId = 0;
hasParentObject = false;

对象b:

id = 2;
parentId = 1;
hasParentObject = true;

对象c:

id = 3;
parentId = 2;
hasParentObject = true;

感谢。

修改

使用以下代码,如何修改代码,以便在对象没有父对象时,对象在具有父对象的任何对象之前位于列表中?

代码:

class Test : IComparable<Test>
{
    public int Id { get; set; }
    public int ParentId { get; set; }
    public bool HasParentObject { get; set; }

    public int CompareTo(Test other)
    {
        if(!this.HasParentObject)
            return 1;
        else if(!other.HasParentObject)
            return 1;
        else if(other.HasParentObject && this.HasParentObject)
            return ParentId.CompareTo(other.ParentId);
        else if(other.HasParentObject)
            return 1;
        else 
            return -1; 
    }
}

4 个答案:

答案 0 :(得分:1)

听起来您希望列表中父项首先出现的对象(可选:按ID排序),然后您希望非父项的对象跟随列表中的父对象(可选:按ID排序) )。

这不是一个单行,但我认为它符合您的要求

using System;
using System.Collections.Generic;
using System.Linq;

public class Program
{
    public static void Main()
    {
        List<Test> tests = new List<Test>
        {
            new Test() { Id = 6, ParentId = 2, HasParentObject = true },
            new Test() { Id = 2, ParentId = 0, HasParentObject = false },
            new Test() { Id = 1, ParentId = 0, HasParentObject = true },
            new Test() { Id = 4, ParentId = 1, HasParentObject = true }
        };

        // Get the parents sorted
        List<Test> sortedTests = tests.Where(t => tests.FindIndex(t2 => t2.ParentId == t.Id) != -1)
            .OrderBy(t => t.Id)
            .ToList();

        // Add those that aren't parents sorted
        sortedTests.AddRange(tests.Where(t => tests.FindIndex(t2 => t2.ParentId == t.Id) == -1)
            .OrderBy(t => t.Id));
        sortedTests.ForEach(t => Console.WriteLine("ID: {0} ParentId: {1}", t.Id, t.ParentId));
    }
}

class Test
{
    public int Id { get; set; }
    public int ParentId { get; set; }
    public bool HasParentObject { get; set; }
}

结果:

ID: 1 ParentId: 0
ID: 2 ParentId: 0
ID: 4 ParentId: 1
ID: 6 ParentId: 2

Fiddle Demo

答案 1 :(得分:0)

您可以为您的班级实施IComparable itherface,然后使用列表中的Sort方法。

class Test : IComparable<Test>
{
    public int Id { get; set; }
    public int ParentId { get; set; }
    public bool HasParentObject { get; set; }

    public int CompareTo(Test other)
    {
        if(other.HasParentObject && this.HasParentObject)
            return ParentId.CompareTo(other.ParentId);
        else if(other.HasParentObject)
            return 1;
        else 
            return -1; 
    }
}

请根据您帖子的数据查看here的工作示例。

答案 2 :(得分:0)

如果可以假设hasParentObject属性是public

    public List<test> l;

    public List<test> sortList(List<test> _l)
    {
        return _l.OrderByDescending(a => a.hasParentObject).ToList();
    }

答案 3 :(得分:0)

您可以使用Sort方法的新比较重载 - .Sort(new Comparison<test>(expression))

例如:

        List<test> list = new List<test>()
        {
            new test() { id=1, hasParentObject = false, parentId = 0 },
            new test() { id=2, hasParentObject = true, parentId = 1 },
            new test() { id=3, hasParentObject = false, parentId = 0 },
            new test() { id=4, hasParentObject = true, parentId = 3 },
        };

        list.Sort((s1, s2) => s1.parentId > s2.parentId ? 1 : (s1.parentId < s2.parentId ? -1 : 0));            

        foreach (var item in list)
            Console.WriteLine(item.id);            

        Console.ReadKey();