【问题标题】:Iterating over different hashes with one method in Ruby在 Ruby 中使用一种方法迭代不同的哈希值
【发布时间】:2019-10-18 04:56:37
【问题描述】:

我一直在研究一个实验室,希望您构建一个接受散列参数的方法 key_for_min_value。该方法应该遍历散列并返回指向集合中最小值的键。如果调用该方法并传递一个空哈希的参数,它应该返回 nil。

我的问题是,必须迭代两个不同的哈希值才能通过测试。我对如何在我的方法中创建逻辑来验证方法中包含的两个部分有点困惑。我曾考虑为我的循环添加更多逻辑,但我不确定这是否是最简洁的编写方式。任何见解将不胜感激。谢谢!

hash = {:blake => 500, :ashley => 2, :adam => 1}
hash = {:blake => 10, :ashley => 50, :adam => 17}

def key_for_min_value(name_hash)
  empty_hash = nil
   name_hash.collect do |name, value|
     if value <= 1
       return name
   end
  end
  empty_hash
end

【问题讨论】:

  • 你的函数没有找到最小值;它正在查找小于或等于1 的值。你不需要更多逻辑,你需要不同逻辑。 #collect 是一个错误的工具。请查看#min_by,或者如果您认为这是作弊,请查看#inject
  • 所以实验室不允许我使用 min_by 和 sort_by。
  • 如果我使用inject vs collect,我很确定我不需要有一个循环,对吗?或者至少没有一个有算术的
  • #collect#inject 都是循环;他们只是做不同的事情。
  • 我很抱歉。我的目标不是将代码提供给我;我真的很想明白这一点!

标签: ruby


【解决方案1】:

在查看了一些视频和文档后,我最终想出了这个:

def key_for_min_value(name_hash)
 smallest_value = 0
 empty_hash = nil
 name_hash.each do |name, value|
  if smallest_value == 0 || value < smallest_value
    smallest_value = value
    empty_hash = name
  end
 end
 empty_hash
end

我担心的是,一旦我到了街区,我就会开始退缩,去创造一些感觉有点干的东西。我运行了这个,我能够通过测试。不过,我不确定这是否会被认为是干净的。我无法使用 sort_by 或 min_by 之类的方法,因此我必须在循环中发挥创意。任何反馈都会很好地说明我如何将其转化为更抽象的东西。

【讨论】:

  • smallest_value 的默认值 0 看起来不正确。它应该从第一个元素的值开始(理想情况下)。
  • 另外empty_hash 一点也不像它的名字:)
  • @SergioTulentsev:对于初学者来说如何从第二个值开始可能不太直观。 nil 有适当的警卫通常是可以的。但是在寻找最小值的情况下,神奇的起始值-Float::INFINITY 非常好(因为您不需要额外的逻辑)。
【解决方案2】:

试试这个:

def key_for_min_value(hash)
  values = hash.values
  hash.keys[values.index(values.min).to_i]
end

values 在最后一个语句中被使用了两次,这就是我分配它的原因。否则,我只会调用hash.values,而该方法只会是 1 行方法。

如果哈希为空,它也会返回nil

【讨论】:

    【解决方案3】:

    你的意思是这样的吗?

    def key_for_min_value(name_hash)
    
        name_hash.reduce([nil, nil]){
            |acc, (key, value)|
            if acc[0].nil?
                [key, value]
            elsif acc[1] > value
                [key, value]
            else
                acc
            end
        }.first
    
    end
    

    有输入:

    hash1 = {:blake => 500, :ashley => 2, :adam => 1}
    hash2 = {:blake => 10, :ashley => 50, :adam => 17}
    hash3 = {}
    

    将产生:

    :adam
    :blake
    nil
    

    【讨论】:

      【解决方案4】:

      你的方法看起来像,

      def key_for_min_value(hash)
        hash.inject { |m,a| m[1] > a[1] ? a : m }[0] unless hash.empty?
      end
      

      【讨论】:

      • 当我们这样做的时候,删除默认的备忘录值参数注入,这里是多余的:)
      • @SergioTulentsev 谢谢,我理解但之前不知道对于数组/哈希,累加器默认值为第一个元素。
      • "for array/hash" - 不仅适用于数组/哈希,这适用于您可以调用 inject 的所有内容。
      猜你喜欢
      • 2019-12-07
      • 1970-01-01
      • 2012-03-24
      • 1970-01-01
      • 1970-01-01
      • 2020-03-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多