1

假设我有一个字符串集合。

List<string> lines = new List<string>(File.ReadAllLines("Test.txt"));

以及用于在该集合中搜索匹配项的正则表达式:

Regex r = new Regex(@"some regular expression");

我怎样才能得到元素的索引,匹配正则表达式?

我有三个想法。


第一个:

var indeces1 = lines.Where(l => r.IsMatch(l))
                    .Select(l => lines.IndexOf(l));
foreach (int i in indeces1)
{
    Console.WriteLine(i);//Do the index-based task instead...
}

我不喜欢它的是IndexOf在原始集合上使用。我错了吗,没关系?


var indeces2 = lines.Select((l, i) => new { Line = l, Index = i })
                    .Where(o => r.IsMatch(o.Line));

foreach (var o in indeces2)
{
    Console.WriteLine(o.Index);//Do the index-based task instead...
}

它似乎比第一个更好,但是有没有办法在不创建匿名对象的情况下做同样的事情?


最后一个:

for (int i = 0; i < lines.Count; i++)
{
    if (r.IsMatch(lines[i]))
    {
        Console.WriteLine(i);//Do the index-based task instead...
    }
}

实际上我现在有这个工作。但是因为我确实喜欢 LINQ,所以我希望有一种 LINQ 方式来做同样的事情。

那么有没有更好的 LINQ 方法来完成这个简单的任务呢?

4

3 回答 3

2

如果你喜欢 LINQ,你可以使用Enumerable.Range更简单:

var indexes = Enumerable.Range(0, lines.Count)
                        .Where(i => r.IsMatch(lines[i]));

编辑:

而不是使用File.ReadAllLines将所有行放入内存:

List<string> lines = new List<string>(File.ReadAllLines("Test.txt"));

如果您的文件很大,您应该考虑使用ReadLines延迟执行以提高效率:

var lines = File.ReadLines("C:\\Test.txt"));
于 2012-12-25T06:06:52.277 回答
2

如果您只需要索引,那么为什么不尝试 .Select(t => t.Index); 在您的选项 2. (最后)仅获取 IEnumerable 索引。您将摆脱 Anonymous 对象。

所以你的查询是:

var indeces2 = lines.Select((l, i) => new { Line = l, Index = i })
        .Where(o => r.IsMatch(o.Line))
        .Select(t => t.Index);
于 2012-12-25T06:17:46.663 回答
0

在这种情况下,我会使用您不起眼的迭代器版本:

for (int i = 0; i < lines.Count; i++)
{
    if (r.IsMatch(lines[i]))
    {
        Console.WriteLine(i);//Do the index-based task instead...
    }
}

对于这种情况,与选项 3 相比,LINQ 并没有真正减少行数并增加可读性。所以在这种情况下,我会选择最简单的版本。

于 2012-12-25T06:19:09.363 回答