列表中的LINQ下一项

时间:2010-04-21 03:59:54

标签: linq

看一下我的问题HERE,我现在想要返回符合条件的下一个推荐对象(之后)。

所以说我找到了第10项中的第6项,我希望查询返回第7项。

或者有更好的方法吗?

7 个答案:

答案 0 :(得分:34)

这是我目前最好的方法:

MyList.SkipWhile(item => item.Name != "someName").Skip(1).FirstOrDefault()

之前的答案使用Skip(1).Take(1),但会返回一个结果的列表。在我的情况下(也许是OP的情况),我们正在寻找实际的项目。所以我的代码跳过它直到它到达我们正在寻找的那个(一个Where会返回一个子集,所以我们将无法访问下一个项目)然后再跳过一个然后获取该项目。

答案 1 :(得分:14)

由于您有一个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")
                                      );

获得索引后,您可以获得下一个项目或上一个项目或任何您想要的项目。

答案 2 :(得分:6)

这样的事情怎么样:

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);

答案 3 :(得分:6)

试试这个


下一个项目

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();

答案 4 :(得分:1)

这个应该这样做。我没有专门为它构建测试。

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语句可以是

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。

答案 5 :(得分:0)

第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);

答案 6 :(得分:0)

如果您确定:

  • 该项目在列表中是唯一的
  • 该项目是从同一个列表中获取的
  • 还有下一项

你可以通过这种方式获得下一个项目

myList[myList.IndexOf(item) + 1];
// or
myList.ElementAt(myList.IndexOf(item) + 1);

如果您不确定是否有下一项,您可以使用 try + catch 或:

myList.ElementAtOrDefault(myList.IndexOf(item) + 1);