如何对具有前置字段的对象的集合进行排序?

时间:2015-11-04 16:46:46

标签: c# .net sorting linked-list

假设我有一个Color

class Color
{
    int id;
    string name;
    int? predecessorId;
    Color(_id, _name, _predecessorId)
    {
        id = _id;
        name = _name;
        predecessorId = _predecessorId;
    }
}

前任ID的目的是我可以拥有一组颜色并任意排序。 (我没有设计这种数据结构。)

假设我有以下七种颜色:

var colors = new []
{
    new Color(0, "red", null),
    new Color(1, "orange", 0),
    new Color(2, "yellow", 1),
    new Color(3, "green", 2),
    new Color(4, "blue", 3),
    new Color(5, "indigo", 4),
    new Color(6, "violet", 5)
}

现在,假设我从外部源接收数据。数据如上所示,但颜色不一定按照predecessorId字段的顺序出现在数组中。但是,我将始终假设predecessorId值始终形成一个完整的链表。

给定一个由七个这些颜色对象组成的数组,我如何对它们进行排序,使第一个颜色对象没有前驱,第二个颜色对象作为其前身,依此类推。

我很清楚有很多方法可以使这只猫,但我使用C#.net,我想尽可能使用内置的框架类,以避免编写更多必须的代码保持。

2 个答案:

答案 0 :(得分:2)

通过找到predecessorId == null的颜色来挑选第一个(并且希望是唯一的)颜色。然后通过将predecessorId的字典索引到颜色直到找不到更多匹配项来找到下一个:

var current = colors.Single(c => c._predecessorId == null);
var sorted = new List<Color> { current };

var colorsByPredecessorId = colors.Where(c => c._predecessorId.HasValue)
                                  .ToDictionary(c => c._predecessorId.Value, c => c);

while (colorsByPredecessorId.ContainsKey(current._id))
{
    current = colorsByPredecessorId[current._id];
    sorted.Add(current);
}

return sorted;

答案 1 :(得分:-2)

我发布了与ryanyuyu相同的东西,但删除了它,因为他快几秒,但看到它似乎做你想要的,他还没有提交它作为答案,我会:

var orderedColors = colors.OrderBy(x => x.predecessorId);

提供如下输出:

enter image description here

所以我不确定你在评论中的意思

  只有在我们可以保证predecessorIds始终按数字顺序排列时,

此处的解决方案才有效。如果我更改了前任ID以反转顺序,则它将不再起作用

源数据的顺序无关紧要。这就是OrderBy的要点。它按照您指定的顺序放置集合。除非您能够澄清要求,否则这应该足够了。