按NextObjectId排序对象列表

时间:2018-05-16 14:42:26

标签: c# linq

我有包含属性Id和NextObjectId的对象列表。 NextObjectId指的是另一个对象的Id告诉该对象它应该在它所引用的对象之后。对象Id是随机的,没有任何特定的顺序。

您能否根据NextObjectId显示如何根据随机顺序将对象列表组织为升级的最有效方式?

4 个答案:

答案 0 :(得分:1)

如果我以正确的方式理解你,你有以下关系: A.Id = B.NextObjectId&& B.Id!= A.Id。

所以你需要用Linq对Id进行排序。

IEnumerable<AClass> orderedObjects = objects.OrderBy(e => e.Id);

或者,如果您想按NextObjectId排序

IEnumerable<AClass> orderedObjects = objects.OrderBy(e => e.NextObjectId);

答案 1 :(得分:1)

我做了这个算法。它应该做你想做的事:

class Program
{
    private static Random random = new Random();
    static void Main(string[] args)
    {
        //GENERATE A RANDOM LIST FOR THE EXAMPLE
        List<Item> items = new List<Item>();
        int? lastID = null;
        for(int i = 0; i < 100; i++)
        {
            int id = random.Next();
            items.Add(new Item() { ID = id, NextItemID = lastID });
            lastID = id;
        }
        //GENERATE A RANDOM LIST FOR THE EXAMPLE

        items = items.OrderBy(x => random.Next()).ToList(); //SHUFFLE THE LIST FOR THE EXAMPLE


        items.OrderByNextItemID(); //SORT THE LIST BY NextItemID
    }
}

public static class Extensions
{
    public static void OrderByNextItemID(this List<Item> items)
    {
        List<Item> results = new List<Item>();
        Item item = items.Where(x => x.NextItemID == null).First();
        results.Add(item);
        items.Remove(item);
        int length = items.Count;
        for(int i = 0; i < length; i++)
        {
            item = items.Where(x => x.NextItemID == results.Last().ID).FirstOrDefault();
            if(item != null)
            {
                results.Add(item);
                items.Remove(item);
            }
        }
        results.Reverse();
        items.AddRange(results);
    }
}

public class Item
{
    public int ID { get; set; }
    public int? NextItemID { get; set; }
}

答案 2 :(得分:0)

我只是从对象ID到对象创建一个字典。从那里开始,假设你有一个起始对象和一些完成方法(例如,NextObjectId为null),你可以建立列表。它不是特别基于LINQ,但它 简单:

YourType item = ...; // Whatever should come first.
var map = objects.ToDictionary(obj => obj.ObjectId);
var list = new List<YourType>();
list.Add(item);
while (item.NextObjectId != null)
{
    // TODO: Handle missing objects? (Use TryGetValue instead of the indexer)
    item = map[item.NextObjectId];
    list.Add(item);
}

答案 3 :(得分:0)

在这里。

如果我理解你,你就有这样的课程:

public class MyObject
{
    public int Id { get; set; }
    public int? NextObjectId { get; set; }
}

List<MyObject>喜欢这个:

List<MyObject> myObjects = new List<MyObject>
    {
        new MyObject {Id = 5, NextObjectId = 4},//4
        new MyObject {Id = 4, NextObjectId = 1},//5
        new MyObject {Id = 2, NextObjectId = 87},//1
        new MyObject {Id = 70, NextObjectId = 5},//3
        new MyObject {Id = 1, NextObjectId = null},//6
        new MyObject {Id = 87, NextObjectId = 70}//2
    };

由于NextObjectId引用了下一个对象Id,因此必须有NextObjectId null(或零),这是最后一个元素,以及它之前的项是前一个元素,其NextObjectId的值等于最后一个元素的Id。我们可以在此算法上构建方法OrderChain

private static IEnumerable<MyObject> OrderChain(List<MyObject> myObjects)
    {
        var starter = myObjects.FirstOrDefault(x => x.NextObjectId == null);
        yield return starter;
        var count = myObjects.Count;
        while (count > 1)
        {
            yield return GetCurrent(myObjects, ref starter);
            count--;
        }
    }

private static MyObject GetCurrent(List<MyObject> lst, ref MyObject current)
    {
        var id = current.Id;
        current = lst.SingleOrDefault(x => x.NextObjectId == id);
        return current;
    }

然后你可以这样排序:

 var myOrderedObjects = OrderChain(myObjects).Reverse().ToList();

这给了我这个清单:

{ Id = 2, NextObjectId = 87 },//1
{ Id = 87, NextObjectId = 70 },//2
{ Id = 70, NextObjectId = 5 },//3
{ Id = 5, NextObjectId = 4 },//4
{ Id = 4, NextObjectId = 1 },//5
{ Id = 1, NextObjectId = null }//6