有了以下代码,还能做得更好吗?
public object DistanceFrom(
IEnumerable<Coordinate> coordinates) {
IEnumerable<DbGeography> addresses = coordinates.Select(
c =>
DbGeography.FromText(String.Format("POINT ({0} {1})", c.Longitude, c.Latitude)));
IEnumerable<VehicleGeography> vehicles = this.GPSInsightProvider.Query().Document.Placemarks.Select(
p =>
new VehicleGeography {
DriverName = p.DriverName,
Point = DbGeography.FromText(String.Format("POINT ({0} {1})", p.Point.Longitude, p.Point.Latitude))
});
ICollection<object> technicians = new List<object>();
foreach (DbGeography address in addresses) {
technicians.Add(vehicles.Select(
v =>
new {
DriverName = v.DriverName,
Distance = v.Point.Distance(address) / 1609.344
}).Where(
v =>
v.Distance.HasValue).OrderBy(
v =>
v.Distance).Take(3).Select(
v =>
new {
DriverName = v.DriverName,
Distance = String.Format("{0:#.#}", v.Distance)
}));
}
return technicians;
}GPSInsightProvider解析KML并返回其对象表示形式。然后,我将其临时转换为VehicleGeography,以便为其创建一个DbGeography属性。然后,我循环遍历我正在检查的地址,然后做一个看上去很脏的计算,看看哪个是离地址最近的三辆车。最多我一次最多要做三个地址。我把得到的对象作为JSON返回到我的web应用程序中。
我很好奇是否有更好的方法来执行整个查找/计算/其他什么-这是?
发布于 2014-10-30 11:29:20
首先,我真的不喜欢您的缩进,特别是方法头的缩进,所以我已经粘贴到Visual中,并将从下面的代码开始工作:
public object DistanceFrom(IEnumerable<Coordinate> coordinates)
{
IEnumerable<DbGeography> addresses = coordinates.Select(c =>
DbGeography.FromText(String.Format("POINT ({0} {1})", c.Longitude, c.Latitude)));
IEnumerable<VehicleGeography> vehicles = this.GPSInsightProvider.Query().Document.Placemarks.Select(p =>
new VehicleGeography
{
DriverName = p.DriverName,
Point = DbGeography.FromText(String.Format("POINT ({0} {1})", p.Point.Longitude, p.Point.Latitude))
});
ICollection<object> technicians = new List<object>();
foreach (DbGeography address in addresses)
{
technicians.Add(
vehicles
.Select(v =>
new
{
DriverName = v.DriverName,
Distance = v.Point.Distance(address) / 1609.344
})
.Where(v =>v.Distance.HasValue)
.OrderBy(v =>v.Distance)
.Take(3)
.Select(v =>
new
{
DriverName = v.DriverName,
Distance = String.Format("{0:#.#}", v.Distance)
}));
}
return technicians;
}我的第一个问题是:为什么返回一个对象?我强烈反对返回匿名类型,您确实应该为这个数据组合创建一个类或结构。其次,您知道最起码,它返回这些匿名类型的列表,因此至少应该返回一个List<object>。
第二:
ICollection<object> technicians = new List<object>();
为什么你要特别减少你要返回的功能?对参数要求最少,返回最多。
在右边使类型明显的变量声明上使用var。当您希望稍后更改该变量的类型时,这将节省额外的输入。
例如:
ICollection<object> technicians = new List<object>();
变成了
var technicians = new List<object>();
您是否有特殊的理由只返回查询的前3名结果?如果是这样的话,这个神奇的数字应该是一个具有合理名称的const。如果不是,它应该是一个变量,同样有一个合理的名称。
1609.344也是如此。我猜这是一种从米到英里的转换,但这本身是没有意义的。
我觉得你的LINQ做得太多了。我建议把它分开一点,这样它所做的事情就更清楚了。毕竟,你已经在遍历地址了,所以把它分开一点。
technicians.Add(
vehicles
.Select(v =>
new
{
DriverName = v.DriverName,
Distance = v.Point.Distance(address) / 1609.344
})
.Where(v =>v.Distance.HasValue)
.OrderBy(v =>v.Distance)
.Take(3)
.Select(v =>
new
{
DriverName = v.DriverName,
Distance = String.Format("{0:#.#}", v.Distance)
}));可能会变成
var vehiclesByDistance =
vehicles
.Select(v =>
new
{
DriverName = v.DriverName,
Distance = v.Point.Distance(address) / 1609.344
})
.Where(v =>v.Distance.HasValue)
.OrderBy(v =>v.Distance);
technicians.Add(
vehiclesByDistance
.Take(3)
.Select(v =>
new
{
DriverName = v.DriverName,
Distance = String.Format("{0:#.#}", v.Distance)
}));最后,我很肯定你的LINQ打破了单一责任原则。它似乎正在执行距离单元转换、排序和格式设置。把这件事分开点也许是明智的。
https://codereview.stackexchange.com/questions/40133
复制相似问题