2010-12-26 3 views
1

Как получить определенный индекс или цикл через эту структуру данных?Looping IEnumerable

public class Path<TNode> : IEnumerable<TNode> 
{ 
    public TNode LastStep { get; private set; } 
    public Path<TNode> PreviousSteps { get; private set; } 
    public double TotalCost { get; private set; } 
    private Path(TNode lastStep, Path<TNode> previousSteps, double totalCost) 
    { 
     LastStep = lastStep; 
     PreviousSteps = previousSteps; 
     TotalCost = totalCost; 
    } 
    public Path(TNode start) : this(start, null, 0) { } 
    public Path<TNode> AddStep(TNode step, double stepCost) 
    { 
     return new Path<TNode>(step, this, TotalCost + stepCost); 
    } 
    public IEnumerator<TNode> GetEnumerator() 
    { 
     for (Path<TNode> p = this; p != null; p = p.PreviousSteps) 
      yield return p.LastStep; 
    } 
    IEnumerator IEnumerable.GetEnumerator() 
    { 
     return this.GetEnumerator(); 
    } 

} 

Используется как график для алгоритма A *. Я хочу сделать 2 вещи с этой структурой данных:

  1. Сформировать график (добавить узлы и их детей)
  2. Уметь пересечь его и найти узел и получить свой конкретный индекс, как: Path<Vector2> node; затем быть в состоянии сделать node[0].
+0

Этот код выглядит очень знакомо http://blogs.msdn.com/ b/ericlippert/archive/2007/10/04/path-find-using-a-in-c-3-0-part-two.aspx –

+0

Ya, его же код. –

+0

Я думаю, что блог был частью серии из четырех частей. Любой шанс, что Эрик упоминает, что вы ищете в остальной части серии? Я признаю, что я слишком ленив, чтобы выглядеть сам. Я буду обвинять его в праздниках;) –

ответ

2

Ну вы можете цикл через него только с петлей Еогеасп:

foreach (Vector2 node in path) 
{ 
    ... 
} 

Правда это выглядит, как он будет перебирать в обратном порядке - если вы хотите, чтобы повернуть его вспять, вы могли бы просто использовать LINQ, как это:

foreach (Vector2 node in path.Reverse()) 

вы можете сделать это, потому что вы реализовали IEnumerable<T>. Насколько я могу судить о том, что доступ к нему по индексу довольно сложный, вы не сможете сделать это особенно эффективно.

Опять же, вы можете использовать LINQ фальсифицировать это - но это будет просто перебирать узлы, пока он не достигнет правого элемента:

Vector2 node = path.ElementAt(2); // Or whatever 
+0

. Можно ли настроить эту структуру данных для более эффективного поиска индекса при сохранении той же функциональности? –

+0

@Shawn: Ну, у вас в основном есть связанный список здесь - и они всегда хороши, когда дело доходит до добавления/удаления узлов с начала и конца и удаления узлов из середины ... но в целом плохо для индексации. Вы могли бы потенциально исследовать структуру на основе дерева или, возможно, основанную на массиве, но в то время как она основана на связанном списке, трудно понять, насколько она будет намного эффективнее. –

+0

Если есть 2 ребенка от одного родителя. Как добавить эти 2 дочерних элемента в родительский узел? –