【问题标题】:LINQ consider comparing elements by doubleLINQ 考虑通过 double 比较元素
【发布时间】:2015-11-16 15:37:03
【问题描述】:

我的目标是按组拆分 IEnumerable 的船只。 船舶群是彼此相距在 0​​.5 英里以内的船舶。

UPD:假设我们有一条河流,比如密西西比州。船只正在通过它漂浮。 我的目标是按他们的位置对他们进行分组。不是坐标而是英里(例如 19.3 英里),因此如果我们有一艘船在 19.3 英里处,而另一艘在 19.5 英里处,我们会将它们归为一组。但是,如果我们在 193 英里范围内还有另一艘船,我们就无法将它添加到我们刚刚分组的两艘船的组中。

ungroupedShips 在我们拥有的船舶集合中:(所有河流和地方) IEnumerable。

我想知道如何在查询中考虑里程比较?

var orderedShips = from ship in ungroupedShips
                   orderby string.Intern(ship.River), ship.MileMarker ascending
                   group ship by string.Intern(ship.River) into shipRiverGroup
                   select new BargeGroup { Ships = shipRiverGroup };

【问题讨论】:

  • 什么是ungroupedShip,它是数据库驱动的 LINQ 提供程序还是 Linq-To-Objects?
  • 你为什么使用string.Intern
  • 对于像这样的复杂任务来说,信息太少了。展示课程以及如何测量距离。
  • @TimSchmelter,我已经更新了详细信息。
  • “分组”的概念仅在您定义了等价类时适用。但是你的关系——两艘船彼此相距在 0​​.5 英里以内——是传递的。您的关系定义了一个图,而不是一个分区。 (如果 A、B、C 在一条直线上,A 为 0,B 为 0.3,C 为 0.6,则 (A, B) 和 (B, C) 彼此相距在 0​​.5 英里范围内,但 (A, C)不是。)

标签: c# algorithm linq logic


【解决方案1】:

我不了解您的 linq,但基于您的问题:

您可以使用 truncate 按数字间隔分组,例如:

context.YourTable
    .GroupBy(g => (int)g.YourFieldDouble)
    .OrderBy(o => o.Key);

这将按整数值分组

如果你想分组为 0.5 到 0.5 个组,只需使用乘法和除法,例如:

context.YourTable
    .GroupBy(g => (int)(g.YourFieldDouble * 2) / 2.0)
    .OrderBy(o => o.Key);

你也可以使用round方法:

context.YourTable
    .GroupBy(g => Math.Round((double)g.YourFieldDouble * 2,
                             MidpointRounding.AwayFromZero) / 2.0)
    .OrderBy(o => o.Key)

【讨论】:

  • 如果一艘船在0.99,另一艘在1.01,他们最终会分成两个不同的组,不是吗?
  • 是的,如果你想让这 2 个在同一个组(组 1)中,你需要使用 round 而不是 truncate。
  • 那解决不了。假设您有三艘船:{ A:0.5, B:1.0, C:1.5},您的代码将输出一组两艘船和另一组一艘船。但是 OP 想要两组两艘船:{A,B}{B,C}
  • 抱歉,我没有得到你需要做的事情,你能改进你的问题吗?尝试更好地解释 group by 将如何构建。
  • 我不是 OP。但问题指出:Group of ships is ships which are within 0.5 of mile between each other.。在我的示例中,{A,B}{B,C} 都与该定义匹配。
【解决方案2】:

由于缺乏信息,我会认为您有这样的 Ship 实体类:

class Ship
{
    public int Id { get; set; }
    public double MileMarker { get; set; }
    public string River { get; set; }
}

所以要让所有在同一条河流中彼此靠近的两艘船:

from s1 in context.Ships
from s2 in context.Ships
where Math.Abs(s1.MileMarker - s2.MileMarker) <= 0.5
   && s1.River == s2.River /* guarantee both ships are in same river. */
   && s1.Id != s2.Id /* avoid pair of one ship with itself. */
   && s1.MileMarker < s2.MileMarker /* avoid permutation duplicity */
select new { S1Mile = s1.MileMarker, S2Mile = s2.MileMarker, River = s1.River }

有这样的场景:

Ships = new List<Ship>
{
    new Ship { Id = 1, MileMarker = 0.2, River = "San" },
    new Ship { Id = 2, MileMarker = 0.4, River = "San" },
    new Ship { Id = 3, MileMarker = 0.8, River = "San" },
    new Ship { Id = 4, MileMarker = 0.1, River = "Joe" },
    new Ship { Id = 5, MileMarker = 0.4, River = "Joe" },
    new Ship { Id = 6, MileMarker = 0.3, River = "Joe" },
};

你会得到:

S1Mile    S2Mile    River

   0.2       0.4    San 
   0.4       0.8    San 
   0.1       0.4    Joe 
   0.1       0.3    Joe 
   0.3       0.4    Joe 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-10
    • 1970-01-01
    • 2019-12-06
    • 2014-06-30
    相关资源
    最近更新 更多