我有包含属性Id和NextObjectId
的对象列表。 NextObjectId
指的是另一个对象的Id
告诉该对象它应该在它所引用的对象之后。对象Id
是随机的,没有任何特定的顺序。
您能否根据NextObjectId
显示如何根据随机顺序将对象列表组织为升级的最有效方式?
答案 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