【问题标题】:How to convert an exclusive range to inclusive range in Ruby?如何在 Ruby 中将独占范围转换为包含范围?
【发布时间】:2019-09-23 12:40:11
【问题描述】:

我有一个独占的整数范围,例如

range = 1000...10001

我宁愿一直使用包含范围,但我这样做的原因是因为当我告诉 ActiveRecord 在 PostgreSQL 中存储一个包含范围时,当我查询它时我得到了独占版本。

我想将它转换成一个包含范围,例如1000..10000

我在做:

(range.begin)..(range.end-1)

但是感觉很笨重而且不像红宝石。

我的整个 API 依赖于传递范围,但我也在考虑记录 2 个值或在 Postgres 中存储一个数组而不是一个范围。

有没有更好的方法来做到这一点?


编辑(一些说明)

考虑到范围之间的巨大差异,我想尽可能高效地做到这一点

我的用例是使用范围的开始和结束部分。我实际上并没有迭代它们或检查包含。我只是认为红宝石范围是表示实际范围的好方法,例如显示价格($ 1.000 - $ 10.000)

【问题讨论】:

  • Range 有一个构造函数Range.new(begin,end,exclude_end=false),但是我不确定这是否对您有帮助。除此之外,您可以定义自己的RangeUtils.to_inclusive(range),但这仅适用于整数。为什么要严格使用包含范围?它们在功能上不是等效的吗?
  • 我的用例是使用范围的beginend 部分。我实际上并没有迭代它们或检查包含。我只是认为红宝石范围是表示实际范围的好方法,例如显示价格($ 1.000 - $ 10.000)
  • 可能相关:github.com/rails/rails/issues/30611 正如您所说,存储 2 个值并动态创建范围可能是更好的解决方案。在 Ruby 中使用范围,在 Postgres 中使用两个整数(或小数)和一个布尔值。
  • @EricDuminil 这正是我的问题,感谢您指出这个问题,我自己无法找到它。它证实了将 ActiveRecord 与 Postgres 范围一起使用并不是很直观

标签: ruby-on-rails ruby activerecord range


【解决方案1】:

我会使用Range#minRange#max

exclusive_range = (1000...10001)
inclusive_range = (exclusive_range.min..exclusive_range.max)
#=> 1000..10000

【讨论】:

  • 有趣的想法。我打消了这个想法,因为我认为它会运行 Array#min 和 max 之类的东西并比较所有值。但现在再想一想,我想它的算法在一定范围内可能更有效,因为它只需要查看末端。你知道这是否有效吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-05
  • 2017-03-22
  • 2010-12-09
  • 1970-01-01
  • 1970-01-01
  • 2022-06-20
相关资源
最近更新 更多