【问题标题】:refer an enumerator value with specified index引用具有指定索引的枚举器值
【发布时间】:2012-06-13 23:42:41
【问题描述】:

假设我有一个可枚举对象enum,现在我想获得第三个项目。

我知道一种通用方法是转换为数组,然后使用如下索引进行访问:

enum.to_a[2]

但是这种方式会创建一个临时数组,可能效率不高。

现在我使用:

enum.each_with_index {|v, i| break v if i == 2}

但这是相当丑陋和多余的。

最有效的方法是什么?

【问题讨论】:

    标签: ruby enumerable


    【解决方案1】:

    您可以使用take 剥离前三个元素,然后使用lasttake 提供给您的数组中获取第三个元素:

    third = enum.take(3).last
    

    如果您根本不想生成任何数组,那么也许:

    # If enum isn't an Enumerator then 'enum = enum.to_enum' or 'enum = enum.each'
    # to make it one.
    (3 - 1).times { enum.next }
    third = enum.next
    

    【讨论】:

    • 这看起来更好,但是,如果我想要一个非常大的数字作为索引,它仍然会为它生成一个非常大的临时数组。
    • @ShouYa:当您发表评论时,我添加了另一个无数组选项。您仍然需要逐个勾选enum,但您对此无能为力(通常)。
    • 使用 next 是一个明智的建议。我很想知道与将集合转换为数组相比,性能影响是什么。
    • @OscarDelBen:这很大程度上取决于枚举器。如果你从一个由 2G 文件支持的枚举器开始,那么转换为一个数组将是可怕的,但调用next 几次几乎是免费的。从技术上讲,枚举器甚至不必是有限的,因此无法保证 to_a 甚至可以工作。
    • 一种将某些内容转换为枚举数的更具声明性的方式:xs.to_enum
    【解决方案2】:

    使用 enumerable-lazy 或 Ruby 2.1 替代 mu 的答案。像使用 next 一样懒惰,但更具声明性:

    enum.lazy.drop(2).first
    

    【讨论】:

      【解决方案3】:

      不幸的是,要通过索引访问成员,必须将其转换为数组(否则您一开始就没有索引),所以您的代码对我来说看起来非常好。

      【讨论】:

      • 嗯,没有。如果eEnumerator,那么2.times { e.next } 将勾选并丢弃前两个值,第三个e.next 将为您提供第三个值而不生成任何数组。
      • @muistooshort 是的,我回复了你的帖子。在这方面你是对的。
      猜你喜欢
      • 2016-06-20
      • 2020-04-03
      • 2018-04-03
      • 1970-01-01
      • 1970-01-01
      • 2011-11-20
      • 2016-08-13
      • 1970-01-01
      • 2019-07-20
      相关资源
      最近更新 更多