【问题标题】:How to compress arrays of integers into an array of ranges and integers in Ruby如何在Ruby中将整数数组压缩为范围和整数数组
【发布时间】:2020-04-28 02:43:41
【问题描述】:

我有一个排序的整数数组,并希望将所有连续整数的子集替换为一个范围,这样:

[1,2,3,4,5,6,7,8,9,10,42]

替换为:

[1..10,42]

这是用户未正确输入的 Google 电子表格中的行列表,无法导入到另一个系统的数据库中。有很多行,通常是几十行。用户更容易看到第 3201-3379 行都是错误的,而不必单独读取每个行号。

我不是要“Array of integers into array of ranges”。

我知道如何编写代码,而且我很乐意这样做,但如果有人已经这样做了,那就不行了。我当前的代码并不优雅,如果已经有一些经过良好测试和优化的东西,我不会费心去重构它。

【问题讨论】:

  • 请求(第 3 方)API / 库有特定的关闭原因。是的,这个任务很有用并且已经被编写(用几十种语言)。不,它不在 Ruby 提供的标准库中。 Ruby 也没有提供标准库函数来生成斐波那契数列。虽然这样很容易编写。
  • “我当前的代码不优雅”——没关系。无论如何,请出示它,以便我们看到您面临的问题。

标签: arrays ruby range


【解决方案1】:

我希望这个问题已经在 SO 提出,但答案不在我的 Rolodesk 中。不过,这很容易做到。

arr = [1, 2, 3, 5, 6, 7, 8, 10, 12, 13, 14, 17, 18, 20]

arr.slice_when { |x,y| y > x+1 }.
    map { |a| a.size == 1 ? a.first : a.first..a.last }
  #=> [1..3, 5..8, 10, 12..14, 17..18, 20]

Enumerable#slice_when

我们首先计算枚举数

enum = arr.slice_when { |x,y| y > x+1 }
  #=> #<Enumerator: #<Enumerator::Generator:0x...0000...fe0>:each>

我们可以将enum 转换为数组,以查看将由枚举器生成并馈送到map 的元素:

enum.to_a
  #=> [[1, 2, 3], [5, 6, 7, 8], [10], [12, 13, 14], [17, 18], [20]]

作为练习,看看是否可以使用另一种Enumerable 方法来代替slice_when。 (提示:考虑Great Peanut Butter Debate。)

【讨论】:

  • 正是我要指向 OP 的位置。 Enumerable 及其文档包含大量信息。这很“优雅”。而且,是的,在某个地方我有一个答案,但在哪里比我好。
  • 哈!有时开始输入比搜索更容易。
猜你喜欢
  • 2017-11-07
  • 2012-01-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-17
  • 1970-01-01
相关资源
最近更新 更多