【问题标题】:Ruby select by indexRuby 按索引选择
【发布时间】:2016-04-16 18:23:25
【问题描述】:

我正在尝试从数组中选择元素:

arr = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n']

其索引是斐波那契数。我想要结果:

['a', 'b', 'c', 'd', 'f', 'i', 'n']

我的代码返回元素和索引。

def is_fibonacci?(i, x = 1, y = 0)
  return true if i == x || i == 0
  return false if x > i
  is_fibonacci?(i, x + y, x)
end

arr.each_with_index.select do |val, index|
  is_fibonacci?(index)
end

此代码返回:

[["a", 0], ["b", 1], ["c", 2], ["d", 3], ["f", 5], ["i", 8], ["n", 13]]

请帮助我了解我如何仍然可以遍历数组并评估索引但只返回元素。

【问题讨论】:

    标签: arrays ruby


    【解决方案1】:

    您可以将代码的最后一位更改为

    arr.select.with_index do |val, index|
      is_fibonacci?(index)
    end
    

    这是有效的,因为如果您调用诸如 select 之类的方法而不使用块,您将获得一个 Enumerator 对象,然后您可以在该对象上链接更多的 Enumerable 方法。

    在这种情况下,我使用了with_index,这与在原始数组上调用each_with_index 非常相似。然而,由于这发生在 select 之后而不是之前,select 从原始数组返回项目,而不附加索引

    【讨论】:

    • 这正是我想要的。我仍然想使用.select。非常感谢!
    【解决方案2】:

    到目前为止,您的代码看起来很棒,我不会更改它。您可以在事后查看您的结果并将[element, index] 对更改为仅包含element by mapping 在每对上,并且仅采用first:

    >> results = [["a", 0], ["b", 1], ["c", 2], ["d", 3], ["f", 5], ["i", 8], ["n", 13]]
    >> results.map(&:first)
    => ["a", "b", "c", "d", "f", "i", "n"]
    

    【讨论】:

      【解决方案3】:

      这是另一种方法。

      index_gen = Enumerator.new do |y|
        i = 0
        j = 1
        loop do
          y.yield i unless i==j
          i, j = j, i + j
        end
      end
        #=> #<Enumerator: #<Enumerator::Generator:0x007fa3eb979028>:each> 
      
      arr.values_at(*index_gen.take_while { |n| n < arr.size })
        #=> ["a", "b", "c", "d", "f", "i", "n"]
      

      或

      index_gen.take_while { |n| n < arr.size }.map { |n| arr[n] }
        #=> ["a", "b", "c", "d", "f", "i", "n"]
      

      注意:

      • 我假设斐波那契数从零(而不是一)开始,这是现代定义。
      • 斐波那契数列开始于0, 1, 1, 2,...。枚举器index_gen 的构造跳过了第二个1。
      • index_gen.take_while { |n| n &lt; arr.size } #=&gt; [0, 1, 2, 3, 5, 8, 13]

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-05-06
        • 1970-01-01
        • 2021-03-08
        • 1970-01-01
        • 2013-10-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多