我找不到相关的问题。
在python
中,您可以轻松遍历序列(list
,generator
等)并同时收集迭代索引,这要归功于enumerate(seq)
这样:
>>> for (i,item) in enumerate(["toto","titi","tutu"]):
... print i, item
...
0 toto
1 titi
2 tutu
IEnumerable是否有类似内容,例如,会转换IEnumerable<T>
中的IEnumerable<Tuple<Int32,T>>
?
(我知道由于Select()
中的正确功能,它很容易完成..但如果它存在,我宁愿使用它:))
更新 仅供参考,我很好奇能够做出类似的事情:“给我满足这个条件的最后一项的索引”,然后通过以下方式完成:
myEnumeration.First(t => some condition on t.Item2 ... ).Item1;
答案 0 :(得分:4)
至于能够做你要求的特定功能,我不知道.NET是否包含它。然而,最快捷的方法就是做这样的事情:
int id = 0;
foreach(var elem in someList)
{
... doStuff ...
id++;
}
编辑:这是一个函数,可以按照您的要求使用yield return
,但它的缺点是每次迭代需要一次GC分配:
public static IEnumerable<Tuple<int, T>> Enumerate<T>(IEnumerable<T> list)
{
int id = 0;
foreach(var elem in list)
{
yield return new Tuple<int, T>(id, elem);
id++;
}
}
答案 1 :(得分:3)
您可以使用Tuple<,>
作为结构,而不是使用KeyValuePair<,>
(这是一个类)。这将在枚举时避免内存分配(不是它们非常昂贵,但仍然如此)。
public static IEnumerable<KeyValuePair<int, T>> Enumerate<T>(this IEnumerable<T> items) {
return items.Select((item, key) => new KeyValuePair(key, item));
}
答案 2 :(得分:2)
这是我自己对自己问题的回答......
如果它不存在,我可以这样做,而不是实际写for
/ foreach
:
var items = new List<String> { "toto", "titi", "tutu" };
var enumerated = items.Select((x, i) => new Tuple<int, String>(i, x));
foreach (var t in enumerated)
{
Console.WriteLine(String.Format("{0} : {1}", t.Item1, t.Item2));
}
打印:
0 : toto
1 : titi
2 : tutu
这是一个单行程......一个丑陋的,但无论如何都是单行:)
答案 3 :(得分:1)
C#7最终允许你以优雅的方式做到这一点:
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}");
}
}
答案 4 :(得分:0)
这是一个扩展方法,它将返回元组序列,其中第一项是序列中的数字,第二项是源序列中的值。
public static IEnumerable<Tuple<int, T>> Enumerate<T>(this IEnumerable<T> source, int start = 0)
{
return source.Select((value, index) => new Tuple<int, T>(index + start, value));
}
示例:
var source = new[] { "apple", "pear", "banana", "orange", "lemon" };
var enumerated1 = source.Enumerate(); // { (0, "apple"), (1, "pear"), (2, "banana"), (3, "orange"), (4, "lemon") }
var enumerated2 = source.Enumerate(3); // { (3, "apple"), (4, "pear"), (5, "banana"), (6, "orange"), (7, "lemon") }