c# - create new object within C# Linq syntax on Select
问题描述
I have a list of Vector2
objects. I want to select a value from each element and sort these values. After that, I want to get the lowest value.
Vector2 cheapestCellPosition = openCells.Select(x => new {
Vector2 = x,
Value = GetCostToTarget(x, targetPosition) + GetCell(x).Cost.GetValueOrDefault()
})
.OrderBy(x => x.Value)
.First();
This code throws an error
CS0029 C# Cannot implicitly convert anonymous type: Sym.Vector2 Vector2, int Value to Sym.Vector2
How can I fix this? I need to setup the Value property based on the current element.
解决方案
UPDATE: You are using this to implement the A-star algorithm. Though the approach you are using works, you will probably be better off if you implement a priority queue; you can get significant performance wins by doing so.
It's unclear why you are going to the trouble of creating a sequence of anonymous types in the first place; why not simply write:
Vector2 cheapestCellPosition = openCells
.OrderBy(x => GetCostToTarget(x, targetPosition) + GetCell(x).Cost.GetValueOrDefault())
.First();
?
Note that though this is more efficient than what you wrote, is not as efficient as it could be.
What you really want is the smallest item in a set. Unfortunately, that is not an operation that is provided in the standard sequence library.
Let's fix that.
What we want to write is:
Vector2 cheapestCellPosition = openCells
.MinBy(x => GetCostToTarget(x, targetPosition) + GetCell(x).Cost.GetValueOrDefault());
Let's suppose the cost is a double, to make it easier.
static class Extensions
{
public static T MinBy(this IEnumerable<T> items, Func<T, double> cost)
{
T minItem = default(T);
double? minCost = null;
foreach(T item in items)
{
double current = cost(item);
if (minCost == null || current < minCost)
{
minCost = current;
minItem = item;
}
}
if (minCost == null) throw InvalidOperationException();
return minItem;
}
}
And we're done. We don't have to sort a list to find the smallest item!
Exercise: Suppose the cost function does not return a double. Can you genericize MinBy
further, so that it can take any cost function?
推荐阅读
- node.js - 使用 Open Id 连接的 AWS IoT 身份验证错误
- python-3.x - Odoo 11 中 inverse_name 的意外行为
- c++ - 如何判断表达式是在编译时还是运行时评估的?
- php - 为什么我的 html 代码不能正常工作
- angular - 滚动时鼠标离开时不会触发 Mouseleave 事件
- oracle - 如何在带有检查约束的 oracle 11g 中将日期与系统日期进行比较?
- codenameone - 侧边菜单和可滚动的表单/容器
- reporting-services - 如何解决我在 Visual Studio 报告中的表达式中除以零的错误?
- c# - 为什么 Entity Framework 由于 Boolean 和 Int 数据类型而无法查询该表?
- android - 当大小变为零时,后退按钮上的 findFragmentById 变为空白