我有一个未排序的对象列表。这些对象有:
我想对列表进行排序,以便任何前面的项目都包含" NextId"等于" PreviousId"紧随其后。
E.g。
第1项:PreviousId = 15,NextId = 16
Item2:PreviousId = 16,NextId = 4
Item3:PreviousId = 4,Next Id = 105
Item4:PreviousId = 105,NextId = 40
我能想到一些"凌乱"方式,但有没有一种标准的方法来做这样的事情?还是一种特别有效的方式?
答案 0 :(得分:2)
如果ID是唯一的,您可以从列表中创建Dictionary<PreviousId, object>
以轻松找到下一个项目。
答案 1 :(得分:1)
请记住,为了简洁起见,我将简化并省略方面以直接满足您的意图。
我假设你有一些内容,但理论上你可以根据你的要求修改Sort
。您可以创建以下内容:
private Enum Sortable { Previous, Next }
private Enum Sorted { Ascending, Descending }
这将为您的Sort
提供干净清晰的简洁参数。现在我们假设您有一个所述项目的模型:
protected void Sort<TKey>(ref List<Model> container, Sorted type, Sortable direction)
{
Comparison<Model> comparison = null;
if(type == "Next")
comparison = (i, j) => i.NextId.CompareTo(j.NextId);
else { comparison = (i, j) => i.PreviousId.CompareTo(j.PreviousId);
return comparison
}
这将是实施Sort
的一种方式。实现是原始的,而且我不担心Ascending
或Descending
,所以你需要定制。一旦实现了所述逻辑的核心,您只需调用:
Sort<Model>(ref model, type, direction);
model
代表您的List<Model>
type
和direction
Enum
代表Sort
的条件。然而,所述实现的逻辑相当广泛,如果您愿意,可以轻松地使用OrderBy
或OrderByDescending
。这可能会为您节省一些时间,因为您的实施更容易。
答案 2 :(得分:1)
抱歉,我没有时间编写代码,但我想,一旦找到匹配的对,就可以通过某种聚合节点在列表中替换它们,因为它们现在有一个“next”和“previous”作为一个整体(第一个项目的前一个项目,第二个项目的下一个项目)。
通过从主搜索中删除任何链接的项目,您将有更少的项目来搜索剩余的链接。 (请原谅糟糕的ASCII示例)
2-3 8-9 1-2 5-6 7-8 4-5
1-3 8-9 5-6 7-8 4-5
(1-2, 2-3)
1-5 8-9 5-6
(1-2, 2-3, 4-5)
您还可以通过检查每个项目的上一个或下一个来提高性能。 Prev可以添加到开头,结尾。
答案 3 :(得分:1)
我已经提出了这个解决方案。
public class SampleObject
{
public string Id { get; set; }
public string Next { get; set; }
}
public List<SampleObject> Sort(List<SampleObject> collection)
{
var sortedCollection = new List<SampleObject>();
foreach (var item in collection)
{
var next = collection.FirstOrDefault(x => x.Id.Equals(item.Next));
if (next != null && !sortedCollection.Contains(next) && !sortedCollection.Contains(item))
{
sortedCollection.Add(item);
sortedCollection.Add(next);
}
}
return sortedCollection;
}
你可以像这样使用它:
var orderedCollection = Sort(yourUnorderedCollection);
答案 4 :(得分:1)
大多数&#34;排序&#34; algorithims不会按照你想要的方式工作,因为它们依赖于能够比较两个随机项,并且比较需要是自反的(如果是&lt; b然后b&lt; a)和传递(如果&lt; b和b&lt; c然后a&lt; c)。
在你的情况下,迭代项目会更简单,可选择按照你想要的顺序将数据放入新的集合中:
Item current = list[0]; // or whatever starting point you need
List<Item> sorted = new List<Item> {current};
while(true)
{
Item next = list.SingleOrDefault(i => i.PreviousID == current.NextID);
if(next == null) // no "next" found - exiting the loop
break;
sorted.Add(next); // add the "next" item to the list
current = next; // set the next" item to the "current" item
}
请注意,您可以对此进行许多改进:
IEnumerator
函数中并使用yield
语句,这样您就不会创建单独的结构Dictionary<int, Item>
?)使查找更快