Autor Beitrag
Bummibaer
Hält's aus hier
Beiträge: 7

Win XP,Solaris,Linux
perl,C#
BeitragVerfasst: Di 10.04.12 17:36 
Hallo,

Warum geht MoveNext ausserhalb der Schleife nicht:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
           List<LinkedList<int>.Enumerator> lEnumerator = new List<LinkedList<int>.Enumerator>();
            for (int i = 0; i < times.Count; i++)
            {
                lEnumerator.Add(times[i].GetEnumerator());
                LinkedList<int>.Enumerator le = times[i].GetEnumerator();
                while (le.MoveNext())           // <- Geht wie erwartet
                {
                    System.Diagnostics.Trace.WriteLine(le.Current);  
                }

            }
            while (lEnumerator[0].MoveNext())   // <- Current bleibt vor erstem Item von times[i] stehen
            {
                System.Diagnostics.Trace.WriteLine(lEnumerator[0].Current);// <- sinnlose Werte ( == 0) 
            }


Danke für Hinweise,

Steffen
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4798
Erhaltene Danke: 1059

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Di 10.04.12 17:58 
Hallo,

du mußt den Enumerator wieder mittels Reset zurücksetzen.

Warum arbeitest du von Hand mit Enumeratoren? Ist das nur ein Test?
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Di 10.04.12 18:02 
times ist eine List von LinkedList's? Ohne zu verstehen wofür der Code gut sein soll fällt es mir schwer Ratschläge zu geben. Was willst du damit erreichen?

@TH69 : Das sind zwei verschiedene Enumeratoren. Muss man aber lange drauf starren um das zu sehen ;)
Bummibaer Threadstarter
Hält's aus hier
Beiträge: 7

Win XP,Solaris,Linux
perl,C#
BeitragVerfasst: Di 10.04.12 18:12 
Tschuldigung, der Enumerator le war nur einTest. Wenn ich den rausnehme, funktioniert es auch nicht:
Hier nochmal die entscheidende Stelle:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
          LinkedList<int> times = new LinkedList<int>();
          List<LinkedList<int>.Enumerator> lEnumerator = new List<LinkedList<int>.Enumerator>();
            for (int i = 0; i < times.Count; i++)
            {
                lEnumerator.Add(times[i].GetEnumerator());
  
            }
            while (lEnumerator[0].MoveNext())   // <- Current bleibt vor erstem Item von times[i] stehen
            {
                System.Diagnostics.Trace.WriteLine(lEnumerator[0].Current);// <- sinnlose Werte ( == 0) 
            }


Ist der Enumerator lokal?
@Th69
ich brauche das, weil ich die Werte nacheinander von einer Zeile in times[] brauche.


Vielen Dank für die schnellen Antworten,
Steffen
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Di 10.04.12 20:42 
Zitat:
ich brauche das, weil ich die Werte nacheinander von einer Zeile in times[] brauche.

Ich sehe keinen Zusammenhang zwischen dieser Aussage und deiner Lösung :gruebel:

Der Enumerator ist ein Struct keine Klasse. Jeder Zugriff über die Indexer Property der Liste in der er steckt liefert dir eine Kopie. Du rufst MoveNext und Current also immer an Kopien des Indexers auf. Current des Indexers in der Liste ist davon aber dann natürlich nicht betroffen. Einmal den Enumerator aus der Liste holen und diese Kopie verwenden sollte helfen.

ausblenden C#-Quelltext
1:
2:
3:
LinkedList<int>.Enumerator enumerator = lEnumerator[0];
while (enumerator.MoveNext())   
    System.Diagnostics.Trace.WriteLine(enumerator.Current);


Ich würde dir raten da grundsätzlich anders dranzugehen. Da ich nicht verstehe was das soll kann ich dir aber nix konkretes empfehlen. Einen statusbehafteter Struct (wie den Enumerator) solltest du aber meiden. Du wirst ständig in so Probleme laufen wie hier. Verlaß dich wenn möglich lieber auf die foreach Magie.

Moderiert von user profile iconTh69: C#-Tags zur Hervorhebung hinzugefügt
Bummibaer Threadstarter
Hält's aus hier
Beiträge: 7

Win XP,Solaris,Linux
perl,C#
BeitragVerfasst: Mi 11.04.12 09:33 
Hallo Ralf,

danke für Deine Bemühungen.
times ist eine List of LinkedList[s]. In ToString() möchte ich über eine Ebene der Liste iterieren.
Etwa so:
ausblenden Quelltext
1:
2:
3:
4:
5:
times[0]  times[1] times[2]
   0 ------ 10 ----- 20
  10 ------ 15  
  30 ------ 40
     ------ 60


Die LinkedList/Queue verwende ich weil ich in Echtzeit sehr viele "times"-Werte bekomme, und die nicht speichern muss.
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
          List<LinkedList<int>> times;
          // ...
          Liste füllen
          // ...
          List<LinkedList<int>.Enumerator> lEnumerator = new List<LinkedList<int>.Enumerator>();
            for (int i = 0; i < times.Count; i++)
            {
                lEnumerator.Add(times[i].GetEnumerator());
  
            }
            while (lEnumerator[0].MoveNext())   // <- Current bleibt vor erstem Item von times[i] stehen
            {
                System.Diagnostics.Trace.WriteLine(lEnumerator[0].Current);// <- sinnlose Werte ( == 0) 
            }


Wenn das nicht hilft, denke ich mir was anderes aus.
Vielen Dank,
Steffen

Moderiert von user profile iconTh69: Code-Tags (zur besseren Ausrichtung als Tabelle) hinzugefügt
Kha
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: Mi 11.04.12 11:02 
Du kannst deine Enumerator-Liste auf IEnumerator<> umstellen, um durch das Boxing die Struct-Probleme zu umgehen. Und dann könntest du den hässlichen Enumerator-Code gleich in einer allgemeinen Transpose-Methode verstecken (z.B. diese hier, nur dass dort das Ergebnis die Länge der kürzesten Liste hat).

_________________
>λ=
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4798
Erhaltene Danke: 1059

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Mi 11.04.12 12:13 
Ich verstehe trotzdem den Sinn der Enumeratoren hier nicht - so wie Ralf schon geschrieben hat (und es auch in der MSDN-Hilfe dazu steht: LinkedList<T>.Enumerator) sollte man die foreach-Schleife dafür benutzen:
MSDN hat folgendes geschrieben:

Hinweise

Die foreach-Anweisung in C# (for each in C++, For Each in Visual Basic) verbirgt die Komplexität der Enumeratoren. Daher empfiehlt es sich, foreach zu verwenden und den Enumerator nicht direkt zu bearbeiten.


Also einfach:
ausblenden C#-Quelltext
1:
2:
3:
4:
foreach (int x in times[0])
{
  Trace.WriteLine(x);
}
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Mi 11.04.12 12:54 
Eine pragmatische Lösung um deine gezeigte tabellarische Ansicht zu generieren sähe zum Beispiel so aus. Der pragmatische Teil ist LinkedList los zu werden um einen direkten indexierten Zugriff auf die Elemente zu haben und damit die Notwendigkeit sich die Position in der LinkedList (per Enumerator) zu merken.

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
for (int i = 0; i < times.Max(x => x.Count); i++)
{
    foreach (var list in times.ConvertAll(x => x.ToArray()))
    {
        if (list.Length > i)
            Console.Write(list[i].ToString().PadRight(8'-'));
        else
            Console.Write("--------");
    }
    Console.WriteLine();
}


Edit : times.ConvertAll sollte man lieber vor die Schleife ziehen um es nicht unnötigerweise mehrmals auszuführen.


Zitat:
Und dann könntest du den hässlichen Enumerator-Code gleich in einer allgemeinen Transpose-Methode


Bei einer nichtrechteckigen Matrix wie hier vermutlich nicht ganz so trivial wie im verlinkten Beitrag. Oder?
Kha
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: Mi 11.04.12 16:01 
user profile iconRalf Jansen hat folgendes geschrieben Zum zitierten Posting springen:
Bei einer nichtrechteckigen Matrix wie hier vermutlich nicht ganz so trivial wie im verlinkten Beitrag. Oder?
Hm, geht so ;) . Kompiliert und nicht getestet:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
    class CompletingEnumerator<T>
    {
      public IEnumerator<T> Inner { get; set; }

      public bool IsCompleted { get; set; }
    }

    public static IEnumerable<IEnumerable<T>> Transpose<T>(this IEnumerable<IEnumerable<T>> source)
    {
      if (source == null)
        throw new ArgumentNullException("source");
      var enumerators = source.Select(x => new CompletingEnumerator<T> { Inner = x.GetEnumerator() }).ToArray();

      try {
        while (true) {
          foreach (var enumerator in enumerators)
            if (!enumerator.Inner.MoveNext())
              enumerator.IsCompleted = true;
          if (enumerators.All(x => x.IsCompleted))
            yield break;

          yield return enumerators.Select(x => x.IsCompleted ? default(T) : x.Inner.Current).ToArray();
        }

      } finally {
        foreach (var enumerator in enumerators)
          enumerator.Inner.Dispose();
      }
    }

_________________
>λ=
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Mi 11.04.12 17:49 
Schick ;) Mal sehen ob es Bummibaer hilft. Ich denke er wird 0 und nicht vorhanden unterscheiden müssen.
Kha
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: Mi 11.04.12 18:11 
Oh, ich hatte irgendwie Listen von Klassen in Erinnerung :O . Dann muss er vor dem Aufruf eben noch nach int? konvertieren ;) .

_________________
>λ=