如何向 Linq 结果添加索引字段

64

假设我有这样一个数组:

string [] Filelist = ...
我想创建一个 Linq 查询结果,每个条目都有它在数组中的位置,像这样:
var list = from f in Filelist
    select new { Index = (something), Filename = f};

第一个项目索引应为0,第二个应为1,以此类推。

我该使用什么表达式来表示 Index = ?

3个回答

142

不要使用查询表达式。 使用 传递索引的重载 Select

var list = FileList.Select((file, index) => new { Index=index, Filename=file });

你如何在SQL语法中实现这个? - toddmo
@toddmo:你所说的“使用SQL语法”是指“使用LINQ查询表达式”吗?如果是这样,那么你不能这样做。如果你的意思是“在SQL本身中”,那我不知道 - 我怀疑有一些非可移植的方法可以实现它。 - Jon Skeet
2
我已经明白了,谢谢。我的意思是这样的:(from GHCOPPADriverType driver in policy.Drivers from GHCOPPADriverHistoryType driverHistory in driver.Rating_DrivingHistory select (driver: driver, history: driverHistory)).Select((t,i) => new DriverHistoryModel(t.history) { DriverId = t.driver.Id, Sequence = i + 1 });。所以,我必须离开查询表达式才能使用Select重载。 - toddmo
@JonSkeet 是王者。谢谢。 - James Harcourt

2
string[] values = { "a", "b", "c" };
int i = 0;
var t = (from v in values
select new { Index = i++, Value = v}).ToList();

4
为什么要费这么大劲,而不使用框架提供的版本? - Jon Skeet
2
但是如果您运行/调用/触发查询两次,您将获得不同的ID - 如果在末尾有一个ToArray来突出显示这一点,我不会介意... - Ruben Bartelink
8
另外,随着可以应用于linq的新并行处理技术,你甚至可以使用相同的数字并且它们不必按顺序排列。哎呀! - Matt DeKrey
1
它使用了另一种语法,不需要lambda表达式。正如我所说,我不建议使用这种方法,只是提供了另一种答案。值得思考。 - GeekyMonkey
1
老话题,我知道.. 但我认为需要注意的是,虽然查询执行多次会返回不同的结果,但仅仅在ToList之后添加ToArray并不会导致这种行为(试一下)。它只是表明,如果你要使用linq,你需要掌握何时执行查询以及其影响。我遇到过一个人试图进行不支持的分组,直到他在基本可查询对象上添加了ToList(),他从数据库中得到了想要的结果,直到有更多的数据。 - vbigham
显示剩余3条评论

1

使用纯LINQ查询表达式(那些带有from.. where.. select..子句的表达式)无法获取索引。

然而,这并不意味着您必须完全放弃这种LINQ查询风格。

您只需要退出LINQ查询表达式并使用.Select(item, index)方法重载即可。

var newestExistingFilesWithIndexes = 
    (from f in Filelist
     // we love LINQ query expressions
     where f.Exists
     // and we use it anywhere possible
     orderby f.LastModified descending
     select f)
     // but sometimes we have to get out and use LINQ extension methods
    .Select((f, index) => new { Index = index, Filename = f.Fullname});

假设您需要根据项目索引过滤列表...
var newestExistingFilesOnlyEvenIndexes = 
     // use the Select method overload to get the index
    (from f in Filelist.Select((file, index) => new { file, index })
     // only take item with an even index
     where f.index % 2 == 0
     where f.file.Exists
     orderby f.file.LastModified descending
     select f.file);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接