6

次のようなハッシュがあるとします。

foo = {
  :bar => ['r', 'baz'], # has a total str length of 4 characters inside of the array
  :baz => ['words', 'etc', 'long words'] # has a total str length of 18 characters inside of the array,
  :blah => ['at'] # has a total str length of 2 characters inside of the array
  # etc...
}

配列に含まれるアイテムの文字列の合計の長さでこのハッシュを並べ替えるにはどうすればよいですか?この場合の結果のハッシュ順序は次のようになります。:blah, :bar, :baz

4

4 に答える 4

12

私はこれをするだけです:

Hash[foo.sort_by { |k, v| v.join.length }]

元のハッシュ値を変更するつもりはなく、並べ替えるだけだと思います。

于 2012-06-08T23:59:56.340 に答える
3

従来、ハッシュは順序付けられていないため、並べ替えることはできません。Ruby 1.9ハッシュは順序付けられていますが、この言語では要素を簡単に並べ替える方法はありません。1.8と同様に、ハッシュを並べ替えるとペアの配列が返されます。

{ c:3, a:1, b:2 }.sort => [ [:a,1], [:b,2], [:c,3] ]

(実際には、シンボルは1.8で比較できないため、1.8はそれを爆破しますが、気にしないでください。)

ただし、ペアのリストに問題がない限り、ハッシュ(または配列)を好きなように並べ替えることができます。sort_byを使用して、ソートキーを抽出するブロックを渡すか、比較を行うブロックでsortを使用します。

foo.sort_by { |key, strings| strings.join.length }

または、最初に最も長いものが必要な場合:

foo.sort_by { |key, strings| -strings.join.length }

次に、1.9を使用していて、結果をハッシュに戻したい場合は、次のように行うことができます(JörgWMittagに感謝)。

Hash[ foo.sort_by { |key, strings| strings.join.length } ]

...これはd11wtqと同じ答えです。

于 2012-06-08T23:43:47.477 に答える
1

ハッシュは、その概念におけるキーの順序を保証しません。ただし、Ruby 1.9では、ハッシュのキー順序が保存されます。したがって、1.9を使用する場合は、他の回答でコードを使用できます。

ただし、これは暗黙的な動作であり、将来の変更を恐れているため、この動作に依存することはお勧めしません。代わりに、文字列の長さの合計の順にハッシュエントリを生成するメソッドを使用してください。

def each_by_length(hash)
  hash = hash.sort_by { |_, strs| strs.map(&:length).inject(0, &:+) }
  hash.each do |k, v|
    yield k, v
  end
end
于 2012-06-08T23:46:18.263 に答える
1
   foo.sort_by { |_,v| v.reduce(:+).size }
于 2012-06-08T23:42:53.870 に答える