【问题标题】:Finding overlapping and gaps between two numbers in a list查找列表中两个数字之间的重叠和间隙
【发布时间】:2020-04-10 17:33:28
【问题描述】:

我有一个如下所示的对象列表:

public class Products
{
    public int ID { get; set; }
    public decimal MinimumPrice { get; set; }
    public decimal MaximumPrice { get; set; }
}

我想对此列表执行两种类型的验证:

a) 值不应重叠(无效输入示例

对象 1:MinimumPrice:1 - MaximumPrice:5

Object2:MinimumPrice:3 - MaximumPrice:6

如果第二个对象是 MinimumPrice: 6 - MaximumPrice: 7 则有效

b) 第二个验证应该是对象之间不会有间隙:

使用上面的示例,如果 Object2 为 MinimumPrice: 8 - MaximumPrice: 9 ,则无效,因为 6 和 7 之间会有差距。

执行这些验证的最佳方法是什么?

【问题讨论】:

  • 我不明白你的样本...
  • 按最小值和最大值排序,然后将每个对象与下一个对象进行比较,看看它们是否重叠或有间隙。
  • 只需要一个比较: Object1.MaximumPrice == Object2.MinimumPrice 您使用十进制,其中可能存在非常小的重叠,如 1.0E-12。这是重叠吗?
  • @Knewit 要应用这些验证,对象列表必须固定顺序并且没有排序?
  • 它看起来像是一个链表,MaximumPrice 与另一个 MinimumPrice+1 链接,直到列表末尾。

标签: c# linq data-structures


【解决方案1】:

您可以先按MinimumPriceOrderBy 对产品进行排序,然后再按MaximumPriceThenBy 对产品进行排序:

var sortedProducts = products
    .OrderBy(product => product.MinimumPrice)
    .ThenBy(product => product.MaximumPrice);

然后你可以制定方法来检查两个产品是否重叠或价格差距:

private static bool ProductsOverlap(Products x, Products y)
{
    return x.MinimumPrice < y.MaximumPrice && y.MinimumPrice < x.MaximumPrice;
}

private static bool ProductsHaveGaps(Products x, Products y)
{
    return y.MinimumPrice - x.MaximumPrice > 1;
}

然后您可以Zip 产品对并检查已排序产品的Any 是否重叠或有间隙:

var overlapOrHaveGaps = sortedProducts
    .Zip(sortedProducts.Skip(1), (x, y) => (x, y))
    .Any(pair => ProductsOverlap(pair.x, pair.y) || ProductsHaveGaps(pair.x, pair.y));

【讨论】:

    【解决方案2】:

    你可以使用 Select 有点冗长的 lambda:

    // Class definition
    public class Range 
    {
        public int Max { get; set; }
        public int Min { get; set; }
        public Range(int min, int max) => (Min, Max) = (min, max);
    }
    
    int prevMax = 0;
    var gaps = ranges.OrderBy(r => r.Min).Select((r, i) =>
    {
        // If index is 0 there's nothing to check.
        // First check is that previous Max is current Min, so
        // we don't have gaps.
        // Second is checking for overlapping.
        // Crucial for this is ordering.
        var noGapAndNoOverlap = i == 0 ? true : prevMax == r.Min && prevMax <= r.Min;
        prevMax = r.Max;
        return noGapAndNoOverlap;
    })
    // Now each elements is true or false, indicating that
    // wether we do not have overlapping or gaps.
    .All(i => i);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-08-06
      • 2017-07-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-02
      • 2020-07-13
      相关资源
      最近更新 更多