这是目前我最好的方法:
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();
ICollection<T>
。我将其改编为仅获取一个结果,使用对象:list.SkipWhile(x => !x.Equals(myObject)).Skip(1).Take(1).SingleOrDefault()
。 - Emy Blacksmith由于您有一个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")
);
一旦你获得了索引,你就可以获取下一个或上一个项目,或者任何你想要的。
这样的东西怎么样:
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);
}
}
Products.Next(x => x.Whatever);
这个应该可以解决问题。我还没有专门为它构建测试。
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。
您可以通过以下方式获取下一个项目
myList[myList.IndexOf(item) + 1];
// or
myList.ElementAt(myList.IndexOf(item) + 1);
如果你不确定是否存在下一个项目,可以使用try
+catch
或者:
myList.ElementAtOrDefault(myList.IndexOf(item) + 1);
项目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);