【问题标题】:How do you Compare Key Value Pairs Ruby你如何比较键值对 Ruby
【发布时间】:2021-07-20 09:30:05
【问题描述】:

在 Ruby 中将散列中的每个键值对相互比较的最简单方法是什么?

例如,

我想对这段代码进行排序,使最高的三个值排在第一位。如果第三个位置的值都相同,那么我想要一个最大的 进入那个位置的钥匙。

{"Aa"=>1, "DDD"=>1, "DdD"=>1, "aA"=>1, "aa"=>1, "bb"=>1, "cC"=>1, "cc"=>1, "ddd"=>3, "e"=>7}

我需要上面的哈希是{"e"=>7, "ddd"=>3, "aa"=>1}

【问题讨论】:

  • Ruby 中的哈希旨在作为 无序 数据结构。如果您需要特定顺序的元素,则不应使用哈希。
  • 不仅需要订购。它基本上是一个大字符串,必须输出出现次数最多的前三个单词。因此,例如,`("e e e e DDD ddd DdD: ddd ddd aa aA Aa, bb cc cC e e e") == ["e", "ddd", "aa"]'。我先对它们进行计数,然后将它们移动到一个数组中,但后来遇到了一个问题,因为我仍然无法按照我需要的方式对它们进行排序,而且我无法得到数字
  • 我可能已经明白了
  • 在这种情况下,请考虑发布问题的答案。我们鼓励人们发布自己问题的答案,以帮助未来访问者遇到类似问题。
  • “如果第三个点的值都相同,那么我想要一个最大的键进入那个点” - 是什么让 "aa" 成为最大的键?

标签: ruby sorting hash


【解决方案1】:

一个字符串 - 最后一个字符串就是你想要的。在.sort 之后添加.reverse 以更改排序方向。 这是一个解决方案:

# two lines for test
m = %w(a a a a a DDD DD ddd Ddd ddd e e e cC cC cC cC b x XXX XXX XXX ZZZ ZZZ ZZZ)
m = %w(n n n KKK KKK KKK KKK KKK LLL LLL LLL kk kk kk kk kk kk kk kk)
m = m.inject(Hash.new(0)) {|h, n| h.update(n => h[n]+1)}
m = m.sort.sort_by {|k, val| -val}.to_h

【讨论】:

  • 哇!这真的很酷!谢谢!是的,看起来效果很好
【解决方案2】:

我会分三步完成:

(1) 将您的哈希 h 转换为对数组:

kv_array = h.to_a

(2) 根据您的标准对数组进行排序:

kv_array.sort! do
  |left, right|
  #.... implement your comparision here
end

(3) 将排序后的数组变成哈希

h_sorted = Hash[kv_array]

【讨论】:

    【解决方案3】:

    按照@tadman 的建议,使用group_by 然后对相关组进行排序会得到你想要的,尽管你需要调整以适应你的实际需要,因为做了很多假设:

    m = {"Aa"=>1, "DDD"=>1, "DdD"=>1, "aA"=>1, "aa"=>1, "bb"=>1, "cC"=>1, "cc"=>1, "ddd"=>3, "e"=>7}
    
    m.group_by { |k,v| v }
     .each_with_object([]) {|a,x| x << [ a[1].compact.map { |b| b[0] }.min, a[0] ] }
     .sort{|a| a[1]}
     .to_h
    
    => {"e"=>7, "ddd"=>3, "Aa"=>1}
    

    解释:

    • 首先我们按值分组(返回一个以该值作为第一个键的哈希,以及匹配的哈希数组)
    • 然后我们收集分组哈希,并为每个分组值找到“第一个”键(使用 min)... * 这是一个假设 * ... 将整个事物作为数组返回
    • 然后我们根据“值”对新数组进行排序
    • 然后我们将数组转换为哈希

    我添加了新行以提高可读性(希望如此)

    【讨论】:

    • 这真的很有趣!谢谢!我喜欢看到人们的代码大脑!
    【解决方案4】:

    我很高兴收到这么多很棒的建议!谢谢!整个问题是获取一个字符串并输出数组中出现的前三个单词。但是,除非它们是单词中的撇号,否则不允许使用特殊字符。如果有多个值并且它们在前三个中,则您必须选择最接近“a”的值。一开始,我使用tally 方法非常快速地添加所有内容,然后我的计划是按值对哈希进行排序,但是当值相同时,我无法放置正确的键值对如果他们共享相同的价值,它必须在哪里。

    所以,我来到这里并询问有关对哈希进行排序的问题,然后意识到我需要完全从头开始我的整个方法。最后,我发现我可以将哈希排序到一定程度,但不能排序到我需要/想要的地方,所以这就是我想出的!

    def top_3_words(str)
      str.scan(/[\w]+'?[\w]*/).sort.slice_when{|a, b| a != b}.max(3){|a, b| a.size <=> b.size}.flatten.uniq
     end 
     
     p top_3_words("a a a  b  c c  d d d d  e e e e e") == ["e", "d", "a"]
     p top_3_words("e e e e DDD ddd DdD: ddd ddd aa aA Aa, bb cc cC e e e") == ["e", "ddd", "aa"]
     p top_3_words("  //wont won't won't ") == ["won't", "wont"]
     p top_3_words("  , e   .. ") == ["e"]
     p top_3_words("  ...  ") == []
     p top_3_words("  '  ") == []
     p top_3_words("  '''  ") == []
     p top_3_words("""In a village of La Mancha, the name of which I have no desire to call to
     mind, there lived not long since one of those gentlemen that keep a lance
     in the lance-rack, an old buckler, a lean hack, and a greyhound for
     coursing. An olla of rather more beef than mutton, a salad on most
     nights, scraps on Saturdays, lentils on Fridays, and a pigeon or so extra
     on Sundays, made away with three-quarters of his income.""") == ["a", "of", "on"]
    

    我的想法是在str 上调用scan,这样我就可以从字符串中取出我不想要的所有内容。然后,我在该返回值上调用了sort,因为最后一个测试用例非常大,我需要将所有类似的词放在一起。在那之后,我在那个返回值上调用了slice_when,并说当a不等于b然后切片,所以会有一个多维数组,然后我可以调用max,因为我排序了早些时候,这些值是按字母顺序排列的,所以如果有一个共享值,它会给我正确的值。我将 3 传递给 max 以获得前三名,然后调用 flatten 所以我有一个数组,uniq 取出多余的字符!!

    这与我最初的问题完全不同,但我想我会分享我正在做的事情,以防将来它可以帮助任何人!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-27
      • 2021-11-15
      相关资源
      最近更新 更多