Linq 索引选择(取两个)
本文关键字:两个 索引 选择 Linq | 更新日期: 2023-09-27 18:35:54
好的,我知道Select((x, i) => ...)
没有文字形式,但我有一个相当复杂的查询,现在有一个新的要求,使一半的投影输出字段依赖于输出"行号"。有没有办法,即使是丑陋的方法,也可以引入索引并以文字形式保留一个查询?
另请注意,并非所有源行都参与结果,因此我不能只是将源投影到可枚举的索引元组中,索引必须在最终投影之前以及所有连接和位置之后应用。
编辑:
原始查询很大,所以把它放在这里毫无意义,让我们用伪简化
from a in source
where somecondition(a)
join b in source2 on a.key equals b.key
where someothercondition(a, b)
select new
{
f1 = a.f1,
oldf2 = func(a.field, b.field),
newf2 = func(a.field, b.field, index)
// ... (20 somthing more projected fields)
}
我需要 newf2 的索引,我需要它而不将查询拆分为两个查询
如果你想要这个"在一个查询中",大多数是"文字形式",你必须执行以下操作:
from t in
(
(
from a in source
where somecondition(a)
join b in source2
on a.key equals b.key
where someothercondition(a, b)
select new { a = a, b = b }
).Select((x, i) => new { index = i, a = x.a, b = x.b } )
)
select new {
f1 = t.a.f1,
oldf2 = func(t.a.field, t.b.field),
newf2 = func(t.a.field, t.b.field, t.index)
// ... (20 somthing more projected fields) }
但这太可怕了。
我宁愿以.
形式将其全部呈现:
a
.Where(a => somecondition(a))
.Join(b, a => a.key, b => b.key, (a,b) => new { a = a, b = b })
.Where(pair => somecondition(pair.a, pair.b))
.Select((t, i) => new
{
f1 = t.a.f1,
oldf2 = func(t.a.field, t.b.field),
newf2 = func(t.a.field, t.b.field, i)
// ...
});
联接语法更丑陋,但至少你没有混淆语法。
你甚至可能更喜欢做
var pairs =
from a in source
where somecondition(a)
join b in source2
on a.key equals b.key
where someothercondition(a, b)
select new { a = a, b = b };
var indexedPairs = pairs.Select((x, i) => new { index = i, a = x.a, b = x.b } );
var projectedIndexedPairs =
from t in indexedPairs
select new {
f1 = t.a.f1,
oldf2 = func(t.a.field, t.b.field),
newf2 = func(t.a.field, t.b.field, t.index)
// ... (20 somthing more projected fields)
};
但这不是"在一个查询中"...
(这是很多 LINQ,其中可能存在一些语法错误,但您可以大致了解。
令人眼花缭乱的灵感闪光
你提到let
魔法让我想起了这一点。它似乎在我写的一个快速示例中有效。
// Copious commenting to explain what you're doing.
int x = 0;
// Copious commenting to explain what you're doing.
var query =
from a in source
where somecondition(a)
join b in source2
on a.key equals b.key
where someothercondition(a, b)
let i = x++
select new {
f1 = a.f1,
oldf2 = func(a.field, b.field),
newf2 = func(a.field, b.field, i),
// ... (20 somthing more projected fields)
};
更新:这是相当脆弱的。例如,如果迭代query
两次,索引将不断递增。(即它不会重置为零。