Ruby有Pair数据类型吗?

i5desfxk  于 11个月前  发布在  Ruby
关注(0)|答案(5)|浏览(106)

有时我需要处理键/值数据。
我不喜欢使用Arrays,因为它们没有大小限制(很容易意外添加超过2个项目,而且您最终需要稍后验证大小)。此外,01的索引成为魔术数字,并且在传达含义方面做得很差(“当我说0时,我实际上是指head...”)。
散列也不合适,因为可能会意外添加额外的条目。
我写了下面的类来解决这个问题:

class Pair
  attr_accessor :head, :tail

  def initialize(h, t)
      @head, @tail = h, t
  end
end

字符串
它工作得很好,解决了这个问题,但我很好奇:Ruby标准库已经有这样一个类了吗?

guykilcj

guykilcj1#

Ruby没有标准的Pair类。
你可以看看“Using Tuples in Ruby?“。
解决方案涉及使用与您类似的类,Tuples gem或OpenStruct
Python有tuple,但即使是Java也没有:“A Java collection of value pairs? (tuples?)“。

vyu0f0g1

vyu0f0g12#

你也可以使用OpenStruct数据类型。可能不是你想要的,但这里有一个实现。

require 'ostruct'

foo = OpenStruct.new
foo.head = "cabeza"
foo.tail = "cola"

字符串
最后,

puts foo.head
 => "cabeza"

puts foo.tail
 => "cola"

cgfeq70w

cgfeq70w3#

不,在Ruby核心库或标准库中没有这样的类。不过,如果有核心库对元组的支持(以及字面语法)就好了。
我曾经尝试过一个与你的类非常相似的类,为了用一个pair替换得到Hash#each的数组,我发现用猴子补丁Hash#each返回一个pair而不是一个数组实际上破坏了令人惊讶的小代码,只要pair类正确地响应to_ato_ary

class Pair
  attr_reader :first, :second

  def to_ary; [first, second] end
  alias_method :to_a, :to_ary

  private

  attr_writer :first, :second

  def initialize(first, second)
    self.first, self.second = first, second
  end

  class << self; alias_method :[], :new end
end

字符串

smdnsysy

smdnsysy4#

Ruby 3.2有一个Data类,可以让你创建带有命名字段的pairs/tuple。

Measure = Data.define(:amount, :unit)
distance = Measure.new(100, 'km') #or Measure.new(amount:100, unit:'km')

distance.amount #=> 100
distance.unit #=> "km"

字符串
查看文档。它比这个例子更灵活:
https://docs.ruby-lang.org/en/3.2/Data.html

wlp8pajw

wlp8pajw5#

你不需要一个特殊的类型,你可以使用一个2元素数组和一个小助手来给予一个一致的顺序。例如:

def pair(a, b)
  (a.hash < b.hash) ? [a, b] : [b, a]
end

distances = {
  pair("Los Angeles", "New York") => 2_789.6,
  pair("Los Angeles", "Sydney") => 7_497,
}

distances[ pair("Los Angeles", "New York") ]    # => 2789.6
distances[ pair("New York", "Los Angeles") ]    # => 2789.6
distances[ pair("Sydney", "Los Angeles") ]      # => 7497

字符串

相关问题