c# - 从 LINQ 查询返回命名元组
问题描述
我整天都在尝试,并且尝试过很多次,但没有运气。我有以下返回结果的 Linq 查询。
此查询返回 IEnumerable<sketchEntity>:
var temp = from entity in remainingEntities
where entity.EndPoint.FuzzyEqual(matchPoint, _tolerance)
select entity;
此查询返回 (IEnumerable<sketchEntity>, end)
var temp = (from entity in remainingEntities
where entity.EndPoint.FuzzyEqual(matchPoint, _tolerance)
select entity, ChainMatchType.End);
这些都不是我想要的。最终 IEnumerable 中的每个结果都需要是一个命名元组,每个元组都有一个 ISketchEntity 和 ChainMatchType:
List<(ISketchEntity sketchEntityName, ChainMatchType MatchName)>
我将在三个不同的时间进行类似的查询。
- 当某些类型的 ISketchEntities 与 EndPoint 匹配时。
- 当某些类型的 ISketchEntities 与 StartPoint 匹配时。
- 当某些类型的 ISketchEntities 与 CenterPoint 匹配时。
当我运行每个查询时,我想使用 Enum 添加结果类型来表示匹配类型。
public enum ChainMatchType
{
Start,
End,
Center
}
我的计划是在返回结果之前将所有三个查询组合成一个结果。
如何格式化我的 LINQ 以将结果转换为命名元组:
Name DataType
entity: ISketchEntity
MatchType: ChainMatchType
EDIT FuzzyEquals 是一个自定义扩展。它使用 +/- 容差比较两个点。我正在使用 CAD 数据,过去的历史告诉我,有时两个点可以接近到相等但没有完全相同的坐标。
public static bool FuzzyEqual(this ISketchPoint sp, ISketchPoint other, double tolerance)
{
if (
sp.X > other.X - tolerance && sp.X < other.X + tolerance &&
sp.Y > other.Y - tolerance && sp.Y < other.Y + tolerance &&
sp.Z > other.Z - tolerance && sp.Z < other.Z + tolerance
)
return true;
return false;
}
刚才看到之后,我想它可以简化为:
public static bool FuzzyEqual(this ISketchPoint sp, ISketchPoint other, double tolerance)
{
return sp.X > other.X - tolerance && sp.X < other.X + tolerance &&
sp.Y > other.Y - tolerance && sp.Y < other.Y + tolerance &&
sp.Z > other.Z - tolerance && sp.Z < other.Z + tolerance;
}
解决方案
- 我建议仅使用带有扩展方法的 Linq,并避免使用关键字样式
from
,in
,where
,select
。- 我承认这是我个人的偏好——但 C# 的 Linq 关键字功能有些不协调,你几乎总是最终需要使用一些扩展方法(尤其是
ToList
andInclude
),并且混合使用关键字和扩展方法样式会使事情变得更难读。
- 我承认这是我个人的偏好——但 C# 的 Linq 关键字功能有些不协调,你几乎总是最终需要使用一些扩展方法(尤其是
- 无论如何,您只需要在一个
Select
步骤中添加值元组,它可以是一个方法参数(尽管您不能轻易地参数化值元组成员名称 - 这是可能的,但超出了这个问题的范围)。
像这样:
List<( ISketchEntity sketchEntityName, ChainMatchType matchName )> withName = remainingEntities
.Where( e => e.EndPoint.FuzzyEqual( matchPoint, _tolerance ) )
.Select( e => ( sketchEntityName: e, matchName: matchName ) )
.ToList()
作为参数化方法:
(我不知道是什么matchPoint
,_tolerance
顺便说一句)。
public static List<( ISketchEntity sketchEntityName, ChainMatchType matchName )> Get2( this IEnumerable<ISketchEntity> entities, ChainMatchType matchType )
{
// Precondition:
if( entities is null ) throw new ArgumentNullException(nameof(entities));
return entities
.Where( e => e.EndPoint.FuzzyEqual( matchPoint, _tolerance ) )
.Select( e => ( sketchEntityName: e, matchName: matchType ) )
.ToList()
}
推荐阅读
- node.js - CentOS8/RHEL8 nodejs 4.9.1以非root用户身份运行时“不允许操作”
- c# - 无法解释此 BitVector32 的状态
- reactjs - 如何解决 React 项目中的 Enzyme/Jest 错误“Cannot find module 'react' from 'react-router.js'”
- android - 导航到 popUpInclusive 不起作用的新目的地
- google-apps-script - 谷歌表格格式
- vba - 为什么 Visio VBA 求幂不起作用?
- python - LightGBM:在多类分类的情况下如何使用 scale_pos_weight?
- kubernetes - Nextflow 未使用正确的服务帐户将工作流部署到 Kubernetes
- php - PHP根据参数重定向到不同的URL
- reactjs - 收藏夹在发布到数据库时不刷新