我在列表中有3个字段(Name,Code,displayNmae),这里我需要获取一个列表作为输出,其中我得到所有字段但需要用冒号分割displayname字段然后再为每个分割添加列表值是显示名称。 因此,在输出列表中,我将有5行,因为总显示名称是2行中的5。 需要linq查询此问题。
名称代码displayName
Napkins_tableware - 餐巾和餐具 - 3_ply:conventional_napkins
手巾 - 手巾和毛巾 - 2_ply:毛巾卷:彩色
输出应该是这样的:
名称 代码displayName
Napkins_tableware - 餐巾和餐具 - 3_ply
Napkins_tableware - 餐巾和餐具 - conventional_napkin
手巾 - 手巾 - 2_ply
手巾 - 手巾 - 毛巾卷
手巾 - 手巾和毛巾
foreach(ProductDetailsWithFilters qs in CategoryProductList())
{
foreach(string friendlyname in qs.displayName.Split(':'))
{
qs.displayName = friendlyname;
tempCategoryProductList.Add(qs);
}
}
答案 0 :(得分:1)
如果你正在翻译LINQ,当你有嵌套的foreach循环时,它们对应于查询语法中的'from'子句(或者在点语法中,后续的变成SelectMany,见下文。)以下内容应该接近你的内容想:
var query =
from qs in CategoryProductList()
from friendlyName in qs.displayName.Split(':')
select new ProductDetailsWithFilters(qs.Code, qs.Category, friendlyName);
注意:由于函数式编程应该是无副作用的,因此最好选择一个新实例ProductDetailsWithFilters
,而不是修改查询中的现有实例。我的假设是你可以调用构造函数来构建一个新的构造函数。
为了修改现有属性,就像你的循环实现那样,你必须迭代结果 - LINQ在框架中没有提供这样的东西。这种副作用通常会导致难以发现的错误。
使用SelectMany和dot-syntax执行上述查询的等效操作:
var query = CategoryProductList()
.SelectMany(
qs => qs.DisplayName.Split(':'),
(qs, friendlyName) => new ProductDetailsWithFilters(qs.Code, qs.Category, friendlyName));
两者都导致功能相同的代码。在这种情况下,我更倾向于使用点语法的查询语法,部分原因是因为有几个SelectMany重载并且处理投影涉及在两个lambda表达式中重复变量。如果您要添加另一个“from”,则查询语法会隐藏“透明标识符”的管理,否则您必须在点语法等效代码中处理这些标识符。无论你喜欢什么,你现在都有。
值得注意的是,查询是懒惰的 - 在迭代结果之前,它们什么都不做。所以你真的用这里的结果来做这个有趣的部分 - 存储它.ToList(),直接数据绑定到UI,用它来为web-API提供服务......等等。