【问题标题】:How to get the key name inside the value for printing inside a Ruby hash如何获取值中的键名以在 Ruby 哈希中打印
【发布时间】:2019-06-17 22:31:07
【问题描述】:

我正在创建一个包含 lambdas 作为 Ruby 值的哈希。我想访问 lambda 中的键名。

哈希是匿名函数 (lambda) 的集合,它们接受输入并执行特定任务。所以,我正在制作一个绘制形状的散列,因此散列中的键是形状名称,如圆形、方形,而这个键的值是一个 lambda,它接受输入并执行一些任务,从而绘制出形状. 所以,在这里我想在 lambda 中打印形状的名称,即键。

真实例子:

MARKER_TYPES = {
        # Default type is circle
        # Stroke width is set to 1
        nil: ->(draw, x, y, fill_color, border_color, size) {
          draw.stroke Rubyplot::Color::COLOR_INDEX[border_color]
          draw.fill Rubyplot::Color::COLOR_INDEX[fill_color]
          draw.circle(x,y, x + size,y)
        },
        circle: ->(draw, x, y, fill_color, border_color, size) {
          draw.stroke Rubyplot::Color::COLOR_INDEX[border_color]
          draw.fill Rubyplot::Color::COLOR_INDEX[fill_color]
          draw.circle(x,y, x + size,y)
        },
        plus: ->(draw, x, y, fill_color, border_color, size) {
          # size is length of one line
          draw.stroke Rubyplot::Color::COLOR_INDEX[fill_color]
          draw.line(x - size/2, y, x + size/2, y)
          draw.line(x, y - size/2, x, y + size/2)
        },
        dot: ->(draw, x, y, fill_color, border_color, size) {
          # Dot is a circle of size 5 pixels
          # size is kept 5 to make it visible, ideally it should be 1
          # which is the smallest displayable size
          draw.fill Rubyplot::Color::COLOR_INDEX[fill_color]
          draw.circle(x,y, x + 5,y)
        },
        asterisk: ->(draw, x, y, fill_color, border_color, size) {
          # Looks like a five sided star
          raise NotImplementedError, "marker #{self} has not yet been implemented"
        }
}

哈希包含大约 40 个这样的键值对。

这个期望的输出是marker star has not yet been implemented

一个简单的例子:

HASH = {
  key1: ->(x) {
   puts('Number of key1 = ' + x.to_s) 
  }
}

而不是硬编码key1,我想在值中获取键的名称,它是一个 lambda,因为哈希中有很多 lambda。

key1 替换为#{self} 会打印类而不是键名。

【问题讨论】:

  • 我明白了。不,哈希值不知道它的键名是什么。哈希是如何创建的?
  • 可以通过遍历散列得到键名,如HASH.each do |key, val|。你能展示一下这个的完整用法吗?你在哪里调用lambas?
  • 已编辑问题,如果仍不清楚,请告诉我。
  • 您在问题中说,“哈希中有很多 lamdas”。您在示例中仅显示一个。了解如何区分它们会很有帮助。另外,您还没有回答我关于如何创建哈希的问题。它是手动完成的还是生成的?根据您似乎要解决的问题,也许哈希真的不是您最终想要做的事情的正确表示?最终了解您要达到的目标会有所帮助。
  • 在回答关于 SO 的问题时,我们遇到了许多 XY 问题,您询问 Y 但应该询问 X。“What is the XY problem?”也许最好描述一下意图;你想做什么,为什么要这样做?另请参阅“How to Ask”和链接页面以及“mcve”,因为它们将帮助您更好地定义问题。

标签: ruby lambda ruby-hash


【解决方案1】:

我不认为这是可以做到的。哈希是键和值的集合。键是唯一的,值不是。您正在询问一个值(在这种情况下是一个 lambda,但它并不重要)它属于哪个键。我可以是一个,没有一个或多个;没有办法让价值“知道”。询问哈希值,而不是值。

【讨论】:

  • 哈希可以反转为数组的哈希,因此可以根据值进行查找,但可以获得可能的 lambda 列表,这只会是另一罐蠕虫。
【解决方案2】:

您正在尝试在 Ruby 中重新实现面向对象的编程。没必要,在 Ruby 中一切都是对象!

您可以删除所有重复的代码、lambdas 和复杂的哈希逻辑:

class MarkerType
  attr_reader :name
  def initialize(name, &block)
    @name = name
    @block = block
  end

  def draw(*params)
    if @block
      @block.call(*params)
    else
      puts "Marker #{name} has not been implemented yet!"
    end
  end
end

square = MarkerType.new 'square' do |size=5|
  puts "Draw a square with size : #{size}"
end

square.draw
# => Draw a square with size : 5


asterisk = MarkerType.new 'asterisk'
asterisk.draw
# => Marker asterisk has not been implemented yet!

【讨论】:

  • 这看起来也不错,但我想避免创建一个新的类,从而避免哈希。感谢您的建议!
猜你喜欢
  • 1970-01-01
  • 2013-09-30
  • 2015-11-15
  • 1970-01-01
  • 2017-12-11
  • 1970-01-01
  • 1970-01-01
  • 2021-12-30
  • 1970-01-01
相关资源
最近更新 更多