I could not find a related question.
In python
you can easily loop through a sequence (list
, generator
etc) and collect the index of the iteration at the same time thanks to enumerate(seq)
like this :
>>> for (i,item) in enumerate(["toto","titi","tutu"]):
... print i, item
...
0 toto
1 titi
2 tutu
Is there something similar for IEnumerable, that would, for instance, transform a IEnumerable<T>
in a IEnumerable<Tuple<Int32,T>>
?
(I know it would be easily done thanks to the correct function in Select()
.. but if it exists, I'd rather use it :) )
UPDATE FYI, I am curious about this kind of possibility to be able to do something like : "give me the index of the last item that fulfils this condition", which would then be accomplished through :
myEnumeration.First(t => some condition on t.Item2 ... ).Item1;
enumerate() is faster when you want to repeatedly access the list/iterable items at their index. When you just want a list of indices, it is faster to use len() and range().
IEnumerable is an interface whose purpose is to provide a way to iterate over a collection. It is one of the most basic and widely used collection interfaces in . NET and implemented by pretty much every collection type (arrays, lists, hashsets, dictionaries, bags, … you name it).
Python enumerate() Function The enumerate() function takes a collection (e.g. a tuple) and returns it as an enumerate object. The enumerate() function adds a counter as the key of the enumerate object.
As in the example above, by default, the index of enumerate() starts at 0. If you want to start from another number, pass the number to the second argument of enumerate() . For example, this is useful when generating sequential number strings starting from 1.
C# 7 finally allows you to do this in an elegant way:
static class Extensions
{
public static IEnumerable<(int, T)> Enumerate<T>(
this IEnumerable<T> input,
int start = 0
)
{
int i = start;
foreach (var t in input)
yield return (i++, t);
}
}
class Program
{
static void Main(string[] args)
{
var s = new string[]
{
"Alpha",
"Bravo",
"Charlie",
"Delta"
};
foreach (var (i, o) in s.Enumerate())
Console.WriteLine($"{i}: {o}");
}
}
Instead of using a Tuple<,>
(which is a class) you can use a KeyValuePair<,>
which is a struct. This will avoid memory allocations when enumerated (not that they are very expensive, but still).
public static IEnumerable<KeyValuePair<int, T>> Enumerate<T>(this IEnumerable<T> items) {
return items.Select((item, key) => new KeyValuePair(key, item));
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With