gpt4 book ai didi

c# - SelectMany 匿名类型并跳过迭代

转载 作者:太空狗 更新时间:2023-10-29 21:34:08 28 4
gpt4 key购买 nike

我已经尝试了很长时间来寻找一种“干净”的模式来处理具有匿名类型的 .SelectMany,当您并不总是希望返回结果时。我最常见的用例如下所示:

  1. 我们有一份客户名单,我想对其进行报告。
  2. 每个客户的数据都驻留在一个单独的数据库中,所以我执行并行 .SelectMany
  3. 在每个 lambda 表达式中,我都会为客户收集结果以形成最终报告。
  4. 如果应跳过特定客户,我需要返回一个空列表。
  5. 我经常使用它们来快速报告,所以我更喜欢匿名类型。

例如,逻辑可能看起来像这样:

//c is a customer
var context = GetContextForCustomer(c);
// look up some data, myData using the context connection
if (someCondition)
return myData.Select(x => new { CustomerID = c, X1 = x.x1, X2 = x.x2 });
else
return null;

这可以作为一个 foreach 语句来实现:

var results = new List<WhatType?>();
foreach (var c in customers) {
var context = GetContextForCustomer(c);
if (someCondition)
results.AddRange(myData.Select(x => new { CustomerID = c, X1 = x.x1, X2 = x.x2 }));
}

或者它可以用 .SelectMany 实现,它用 .Where 预先过滤:

customers
.Where(c => someCondition)
.AsParallel()
.SelectMany(c => {
var context = GetContextForCustomer(c);
return myData.Select(x => new { CustomerID = c, X1 = x.x1, X2 = x.x2 });
})
.ToList();

这两种方法都存在问题。 foreach 解决方案需要初始化一个List 来存储结果,并且您必须定义类型。 .SelectMany.Where 通常是不切实际的,因为 someCondition 的逻辑相当复杂并且依赖于一些数据查找。所以我理想的解决方案看起来像这样:

customers
.AsParallel()
.SelectMany(c => {
var context = GetContextForCustomer(c);
if (someCondition)
return myData.Select(x => new { CustomerID = c, X1 = x.x1, X2 = x.x2 });
else
continue? return null? return empty list?
})
.ToList();

我应该在 else 行中输入什么来跳过返回值?我无法提出或理想的解决方案:

  1. continue 无法编译,因为它不是事件的 foreach 循环
  2. return null 导致 NRE
  3. 返回空列表需要我重新初始化一个匿名类型的列表。

有没有一种方法可以做到上述的干净、简单、整洁,并且满足我所有(挑剔)的要求?

最佳答案

你可以返回一个空的 Enumerable<dynamic> .这是一个示例(尽管没有您的客户和 someCondition ,因为我不知道它们是什么,但与您的示例具有相同的一般形式):

new int[] { 1, 2, 3, 4 }
.AsParallel()
.SelectMany(i => {
if (i % 2 == 0)
return Enumerable.Repeat(new { i, squared = i * i }, i);
else
return Enumerable.Empty<dynamic>();
})
.ToList();

因此,使用您的对象和 someCondition , 它看起来像

customers
.AsParallel()
.SelectMany(c => {
var context = GetContextForCustomer(c);
if (someCondition)
return myData.Select(x => new { CustomerID = c, X1 = x.x1, X2 = x.x2 });
else
return Enumerable.Empty<dynamic>();
})
.ToList();

关于c# - SelectMany 匿名类型并跳过迭代,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20158953/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com