【发布时间】:2010-04-21 03:59:54
【问题描述】:
【问题讨论】:
标签: linq
【问题讨论】:
标签: linq
这是我目前最好的方法:
MyList.SkipWhile(item => item.Name != "someName").Skip(1).FirstOrDefault()
较早的答案使用Skip(1).Take(1),它有效,但返回一个结果列表。在我的情况下(也许是 OP 的情况),我们正在寻找实际的项目。所以我的代码会跳过,直到它到达我们正在寻找的那个(一个 Where 将返回一个子集,因此我们无法访问下一个项目)然后再跳过一个,然后获取该项目。
【讨论】:
试试这个
下一项
MyList.SkipWhile(x => x != value).Skip(1).FirstOrDefault();
上一个项目注意:Reverse() 不适用于 LINQ to SQL
var MyList2 = MyList.ToList();
MyList2.Reverse();
MyList2.SkipWhile(x => x != value).Skip(1).FirstOrDefault();
【讨论】:
Reverse在SQL Server中没有实现。
ICollection<T> 完美配合。我对此进行了调整,只得到一个结果,对象为:list.SkipWhile(x => !x.Equals(myObject)).Skip(1).Take(1).SingleOrDefault()。
如果你确定:
您可以通过这种方式获得下一个项目
myList[myList.IndexOf(item) + 1];
// or
myList.ElementAt(myList.IndexOf(item) + 1);
如果您不确定是否有下一项,您可以使用try + catch 或:
myList.ElementAtOrDefault(myList.IndexOf(item) + 1);
【讨论】:
这样的事情怎么样:
public static class Extension
{
public static T Next<T>(this IEnumerable<T> source, Func<T, bool> predicate)
{
bool flag = false;
using (var enumerator = source.GetEnumerator())
{
while (enumerator.MoveNext())
{
if (flag) return enumerator.Current;
if(predicate(enumerator.Current))
{
flag = true;
}
}
}
return default(T);
}
}
然后你可以像在 Where 中那样调用它
Products.Next(x => x.Whatever);
【讨论】:
由于您有一个List<T> 对象,您可以使用它的FindIndex 方法而不是Where 来获取第一个匹配项的索引而不是该项本身:
int index = recommendations.FindIndex(rp =>
rp.Products.Any(p => p.Product.Code == "A")
&& rp.Products.Any(p => p.Product.Code == "B")
);
一旦你有了索引,你就可以得到下一个或上一个或任何你想要的。
【讨论】:
这应该这样做。我还没有专门为它构建测试。
var nextProducts = from item1 in recommendations.Select((rec, idx) => new { Rec = rec, Index = idx })
join item2 in recommendations.Select((rec, idx) => new { Rec = rec, Index = idx })
on item1.Index equals item2.Index - 1
where item1.Rec.Products.Any(p => p.Code == "A")
&& item1.Rec.Products.Any(p => p.Code == "B")
select item2.Rec;
如果你需要两条记录,选择语句可以是
select new { MatchingItem = item1.Rec, NextItem = item2.Rec };
但是您必须进行分组以说明匹配项是列表中的最后一项(在这种情况下不会有下一项)。
var nextProducts = from item1 in recommendations.Select((rec, idx) => new { Rec = rec, Index = idx })
join item2 in recommendations.Select((rec, idx) => new { Rec = rec, Index = idx })
on item1.Index equals item2.Index - 1
into groupjoin
from i2 in groupjoin.DefaultIfEmpty ()
where item1.Rec.Products.Any(p => p.Code == "A")
&& item1.Rec.Products.Any(p => p.Code == "B")
select new { MatchingItem = item1.Rec, NextItem = i2 == null ? null : i2.Rec };
我做测试的代码类似于字符串列表。
List<string> list = new List<string>() { "a", "b", "c", "a", "d", "a", "e" };
var query = from item1 in list.Select((s, idx) => new { Item = s, Index = idx })
join item2 in list.Select((s, idx) => new { Item = s, Index = idx })
on item1.Index equals item2.Index - 1
where item1.Item == "a"
select item2.Item;
返回 b、d 和 e。
【讨论】:
第 7 项是否与您的 Where 子句匹配?如果是这样,请使用Skip() 和Take() 扩展方法:
var myProducts =
from rp in recommendations
where
cp.Products.Any(p => p.Product.Code == "A") &&
cp.Products.Any(p => p.Product.Code == "B")
select rp;
var nextProduct = myProducts.Skip(1).Take(1);
【讨论】: