Gibt es ein C#-Äquivalent zu Pythons enumerate()
und Ruby's each_with_index
?
Können Sie in dieser foreach-Schleife nicht unterbrechen.
Gibt es ein C#-Äquivalent zu Pythons enumerate()
und Ruby's each_with_index
?
Ich behalte diese Erweiterungsmethode für diesen Zweck bei:
public static void Each<T>(this IEnumerable<T> ie, Action<T, int> action)
{
var i = 0;
foreach (var e in ie) action(e, i++);
}
Und verwenden Sie es so:
var strings = new List<string>();
strings.Each((str, n) =>
{
// hooray
});
Oder um zu ermöglichen break
-ähnliches Verhalten:
public static bool Each<T>(this IEnumerable<T> ie, Func<T, int, bool> action)
{
int i = 0;
foreach (T e in ie) if (!action(e, i++)) return false;
return true;
}
var strings = new List<string>() { "a", "b", "c" };
bool iteratedAll = strings.Each ((str, n)) =>
{
if (str == "b") return false;
return true;
});
Sie können Folgendes tun
foreach (var it in someCollection.Select((x, i) => new { Value = x, Index = i }) )
{
if (it.Index > SomeNumber) //
}
Dadurch wird für jeden Eintrag in der Sammlung ein Wert vom anonymen Typ erstellt. Er hat zwei Eigenschaften
Value
: mit dem ursprünglichen Wert in der SammlungIndex
mit dem Index innerhalb der Sammlung
Clever, aber das ist so, als würde man sich mit der rechten Hand am linken Ohr kratzen. Ich schätze, ich werde den Index einfach selbst behalten, damit ich zukünftige Betreuer nicht verwirre.
@Neil, ich bin erstaunt, dass die Leute glauben, dies sei ein Wartungsproblem. Diese Überladung von Select (und anderen LINQ-Methoden) wurde genau zu dem Zweck bereitgestellt, um Operationen wie diese durchzuführen.
Die C# foreach hat keinen eingebauten Index. Sie müssen außerhalb der foreach-Schleife eine Ganzzahl hinzufügen und diese jedes Mal inkrementieren.
int i = -1;
foreach (Widget w in widgets)
{
i++;
// do something
}
Alternativ können Sie auch eine standardmäßige for-Schleife wie folgt verwenden:
for (int i = 0; i < widgets.Length; i++)
{
w = widgets[i];
// do something
}
Ich denke, Sie sollten i auf -1 initialisieren und zu Beginn des Schleifenkörpers inkrementieren, um sicherzustellen, dass eine "continue"-Anweisung keine Probleme verursacht.
@DrJokepu warum behalten Sie nicht einfach i = 0 und inkrementieren es vor der schließenden Klammer der foreach-Anweisung? Die Initialisierung mit etwas != 0 erregt die Aufmerksamkeit, wenn man später den Code durchsucht...
Abgesehen von den bereits gegebenen LINQ-Antworten, habe ich eine "SmartEnumerable" Klasse, die es Ihnen ermöglicht, den Index und die "first/last"-ness zu erhalten. Es ist ein bisschen hässlich in Bezug auf die Syntax, aber Sie können es nützlich finden.
Wir können wahrscheinlich die Typinferenz mit einer statischen Methode in einem nicht-generischen Typ verbessern, und implizite Typisierung wird auch helfen.
Ich mag die Möglichkeit, foreach zu verwenden, also habe ich eine Erweiterungsmethode und eine Struktur erstellt:
public struct EnumeratedInstance<T>
{
public long cnt;
public T item;
}
public static IEnumerable<EnumeratedInstance<T>> Enumerate<T>(this IEnumerable<T> collection)
{
long counter = 0;
foreach (var item in collection)
{
yield return new EnumeratedInstance<T>
{
cnt = counter,
item = item
};
counter++;
}
}
und ein Anwendungsbeispiel:
foreach (var ii in new string[] { "a", "b", "c" }.Enumerate())
{
Console.WriteLine(ii.item + ii.cnt);
}
Eine gute Sache ist, dass Sie die Python-Syntax auch dann verwenden können, wenn Sie mit ihr vertraut sind:
foreach (var ii in Enumerate(new string[] { "a", "b", "c" }))
Entschuldigung für den Necropost. Ich modifiziert Ihre Funktion, so dass es hübsch und mehr pythonic in Gebrauch aussieht: pastebin.com/aExvenyY
CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.
0 Stimmen
Wenn Sie LINQ verwenden, gibt es Überschreibungen der verschiedenen Funktionen, die eine Aufzählung ermöglichen. Ansonsten müssen Sie in der Regel eine Variable verwenden, die Sie selbst inkrementieren.
1 Stimmen
Können wir diese Frage auf C# 7.0 aktualisieren, wo es jetzt Tupel gibt? Ich frage mich, wie eine Lösung mit Tupeln aussehen würde.
0 Stimmen
Ist das nicht ein Merkmal von
foreach
dass Sie jedes Element absolut entkoppelt von seiner Position in der Liste verarbeiten können?