使用LINQ获取序列的奇数/偶数部分

本文关键字:数部 LINQ 获取 使用 | 更新日期: 2023-09-27 17:48:49

假设我有一个所有Projects的列表,并按照Category对它们进行分组,如下所示:

var projectsByCat = from p in Projects
                    group p by p.Category into g
                    orderby g.Count() descending
                    select new { Category = g.Key, Projects = g };

现在我想将其显示为网页中的列表,首先我创建左侧div,其次是右侧div。我在每个Category中按Projects的数量排序,以显示顶部有最多ProjectsCategories-因此我想将projectsByCat一分为二-如果我将所有";奇数编号的";左边的CCD_ 8;偶数的";分类在右边,我想我会得到一个合理理智的观点。

所以我想我可以这样做来获得projectsByCat:的奇数和偶数成员

var oddCategories = projectsByCat.Where((cat, index) => index % 2 != 0);
var evenCategories = projectsByCat.Where((cat, index) => index % 2 == 0);

它进行编译——然而,当我运行它时,我会得到这样一个异常:

不支持用于查询运算符"Where"的重载。

我认为我是安全的,因为它从一开始就编译了。;)

有没有一种优雅的方法可以做到这一点?还有,有没有一个优雅的解释,为什么我创造性地使用Where()不起作用?

使用LINQ获取序列的奇数/偶数部分

如果使用LINQ to SQL或LINQ to Entities,则应首先将结果完全具体化到内存中:

var oddCategories  = projectsByCat.ToList().Where((c,i) => i % 2 != 0);
var evenCategories = projectsByCat.ToList().Where((c,i) => i % 2 == 0);

在不使用游标的情况下,使用索引器在数据库上迭代结果是不可能的,这是ORM框架所做的而不是所做的。

请注意,对同一查询调用.ToList()两次将对数据库进行两次查询。

最好将结果缓存在中间列表中,然后应用谓词过滤:

var projectsByCat =
    (from p in Projects
    group p by p.Category into g
    orderby g.Count() descending
    select new { Category = g.Key, Projects = g }).ToList();
var oddCategories = projectsByCat.Where((cat, index) => index % 2 != 0);
var evenCategories = projectsByCat.Where((cat, index) => index % 2 == 0);

oddCategories和evenCategories是向后的。

索引启动0而不是1

0%2=0

0索引是奇数。

var oddCategories  = projectsByCat.Where((cat, index) => index % 2 == 0);
var evenCategories = projectsByCat.Where((cat, index) => index % 2 != 0);

使用LINQ并避免对输入进行多次枚举的正确方法是对每个项是偶数还是奇数进行分组或类似操作。

一种简单的方法是使用Select的重载,该重载混合在与ToLookup耦合的索引中,可以提供您想要的内容:

var oddsAndEvens = input
    .ToList() // if necessary to get from IQueryable to IEnumerable
    .Select((item, index) => new { isEven = index % 2 == 0, item })
    .ToLookup(
        i => i.isEven,
        i => i.item);

这将产生具有以下优点的Lookup<TKey, TElement>数据结构:

如果在集合中找不到键,则返回一个空序列。

这意味着,在上述LINQ查询之后,您可以执行以下操作:

var evens = oddsAndEvens[true];
var odds = oddsAndEvens[false];

您可以使用linq在视图中分离奇数和偶数。

//even 
@foreach (var item in Model.Where((item, index) => index % 2 == 0))
{
     //do the code
}
//odd
@foreach (var item in Model.Where((item, index) => index % 2 != 0))
{
     //do the code
}

您可以在没有foreach循环的情况下找到偶奇数

static void Main(string[] args)
{
    List<int> lstnum = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
    List<int> lstresult = lstnum.FindAll(x => (x % 2) == 0);
    lstresult.ForEach(x => Console.WriteLine(x));
}
var text = "this is a test <string> to extract odd <index> values after split";
var parts = text.Split(new char[] { '<', '>' });
IEnumerable words = parts.Where(x => parts.ToList().IndexOf(x) % 2 == 1)

单词将包含"字符串"answers"索引"

使用Linq GroupBy方法:

    List<string> lista = new List<string> { "uno", "dos", "tres", "cuatro" };
    var grupoXindices = lista.GroupBy(i => (lista.IndexOf(i) % 2) == 0);
    foreach (var grupo in grupoXindices) 
    {
    Console.WriteLine(grupo.Key);                
    foreach (var i in grupo) Console.WriteLine(i);
    }