2009-10-08 11 views

Odpowiedz

15

Mam typ w MiscUtil, który może pomóc w tym - SmartEnumerable. To głupie imię, ale działa :) Zobacz usage page szczegóły, a jeśli używasz C# 3 można zrobić to jeszcze prostsze:

foreach (var item in temptable.Rows.AsSmartEnumerable()) 
{ 
    int index = item.Index; 
    DataRow value = item.Value; 
    bool isFirst = item.IsFirst; 
    bool isLast = item.IsLast; 
} 
+0

+1 za Imię :) – nawfal

20

Trzeba stworzyć samemu

var i = 0; 
foreach (DataRow temprow in temptable.Rows) 
{ 
    this.text = i; 
    // etc 
    i++; 
} 

lub można po prostu zrobić dla pętli zamiast.

+5

+1, choć rzadko (jeśli w ogóle) zalecałbym "za" zamiast "foreach". Różne mechanizmy pamięci masowej mogą bardzo słabo radzić sobie z wyszukiwaniem opartym na indeksie (na przykład na połączonej liście) i bardzo dobrze na wyliczaniu bezpośrednim. –

+0

@Adam Zrozumiałe, pomiar jest prawdopodobnie najlepszą rzeczą, aby dowiedzieć się, która droga byłaby lepsza. – Joseph

1
int rowIndex = temptable.Rows.IndexOf(temprow); 
+2

Chciałbym poradzić sobie z tym. Prawdopodobnie kosztowałoby to o wiele więcej niż użycie własnego inkrementatora. –

+0

Ustawiłem breakpoint w części podczas długiej pętli foreach podczas testowania i użyłem tego w oknie zegarka, aby pomóc określić, ile jeszcze musiałem przejść. Wystarczająco dobry do debugowania :) – NotMe

0

Albo użyć pętli for lub użyj liczbą całkowitą podążać:

int count =0; 
foreach (DataRow temprow in temptable.Rows) 
{ 
    //count is the index of the row in the array temptable.Rows 
    //this.text = temprow.INDEX???? 
    ++count; 
} 
5

Ty naprawdę nie. Jedną z piękności z foreach jest to, że nie masz dodatkowego zestawu inkrementacji obsługi kodu i kontroli długości.

Jeśli chcesz mieć swój własny indeks trzeba by zrobić coś takiego

int rowindex = 0; 
foreach (DataRow temprow in temptable.Rows) 
{ 
//this.text = temprow.INDEX???? 
    this.text = rowindex++; 
} 
1

nie jest to możliwe ze standardowym pętli foreach. Najprostszym sposobem jest użycie pętli for

for (int i = 0; i < temptable.Rows.Count; i++) { 
    DataRow temprow = (DataRow)temptable.Rows[i]; 
    ... 
} 

Inną opcją jest użycie metodę rozszerzenia

public static void ForEachIndex<T>(this IEnumerable<T> e, Action<T,int> del) { 
    var i = 0; 
    foreach (var cur in e) { 
    del(cur,i); 
    } 
} 

...

temptable.Rows.Cast<DataRow>.ForEachIndex((cur,index) 
{ 
    ... 
}); 
0

Można użyć standardowego for pętlę, aby uzyskać indeks

for(int i=0; i<temptable.Rows.Count; i++) 
{ 
    var index = i; 
    var row = temptable.Rows[i]; 
} 
0

Podczas gdy odpowiedź LFSR ma rację, jestem prawie pewny, że wywołanie .IndexOf na prawie każdej kolekcji/liście będzie wyliczać listę, dopóki nie znajdzie pasującego wiersza. Dla dużych DataTable może to być powolne.

Może być lepiej dla (i = 0; i < temptable.Rows.Count; i ++) {...} nad tabelą. W ten sposób masz indeks bez narzucania podatku od znalezienia indeksu.

11

Jeśli można użyć LINQ, możesz zrobić to w ten sposób :

foreach (var pair in temptable.Rows.Cast<DataRow>() 
            .Select((r, i) => new {Row = r, Index = i})) 
{ 
    int index = pair.Index; 
    DataRow row = pair.Row; 
} 
+0

Człowieku, właśnie chciałem wprowadzić tę odpowiedź ... no cóż –

+0

Uwielbiam to! Dzięki! – Lukas

1

Hej, myślę, że jest o wiele szybciej. Nie jest wymagana żadna iteracja! Najpierw zadeklarować zmienną statyczną do znajomego rowid Dziedzina DataRow:

Private Shared RowIDFieldInfo As System.Reflection.FieldInfo = GetType(DataRow).GetField("_rowID", System.Reflection.BindingFlags.NonPublic Or System.Reflection.BindingFlags.Instance) 

to wszystko, co trzeba zrobić, aby go używać to:

RowIDFieldInfo.GetValue(MyDataRow) - 1 

Nie testowałem tego po uciekania lub filtrowania . W moim przypadku nie mam takiej potrzeby, więc to działa.

1

Lepiej późno niż wcale ...

foreach (DataRow temprow in temptable.Rows) 
{ 
    temptable.Rows.IndexOf(temprow); 
} 
Powiązane problemy