숫자 값으로 루비 해시를 정렬하는 방법?


154

개수별로 정렬하려고하는 카운터 해시가 있습니다. 내가 겪고있는 문제는 기본 Hash.sort 함수가 숫자 크기가 아닌 문자열처럼 숫자를 정렬한다는 것입니다.

즉 해시 :

metrics = {"sitea.com" => 745, "siteb.com" => 9, "sitec.com" => 10 }

이 코드를 실행 :

metrics.sort {|a1,a2| a2[1]<=>a1[1]}

정렬 된 배열을 반환합니다 :

[ 'siteb.com', 9, 'sitea.com', 745, 'sitec.com', 10]

745가 9보다 큰 경우에도 9가 목록에 먼저 나타납니다. 누가 가장 많은 수의 사람을 보여 주려고 할 때, 이것은 내 인생을 어렵게 만듭니다. :)

숫자 값 크기로 해시 (또는 배열)를 정렬하는 방법에 대한 아이디어가 있습니까?

도움을 주셔서 감사합니다.


어떤 루비 버전을 사용하십니까? 정렬 결과가 매우 이상합니다
— fl00r

답변:


268

당신이 종류의 문자열 값으로 ... 당신은 반대해야하지 것이기 때문에, 결과를 얻었는지 아무 생각이 a1와 a2당신의 예에서

어떤 경우에도 (Mladen에 따라) 가장 좋은 방법은 다음과 같습니다.

metrics = {"sitea.com" => 745, "siteb.com" => 9, "sitec.com" => 10 }
metrics.sort_by {|_key, value| value}
  # ==> [["siteb.com", 9], ["sitec.com", 10], ["sitea.com", 745]]

결과적으로 해시가 필요한 경우 to_h(Ruby 2.0 이상에서)

metrics.sort_by {|_key, value| value}.to_h
  # ==> {"siteb.com" => 9, "sitec.com" => 10, "sitea.com", 745}

84
또는 간단히sort_by{|k,v| v}
— Mladen Jablanović

내 번호는 문자열로 반환되어 수정되었습니다. 결과가 정렬되도록 정렬하기를 원했기 때문에 순서대로 a2와 a1이있었습니다. 피드백에 감사드립니다.
— Dustin M.

이것이 내가 루비를 좋아하는 이유입니다 ... 그러한 문제는 다른 언어로 머리에 통증이 있습니다. 너무 간단
— Hady Elsahar

18
@Elchin : 사용 가능metrics.sort_by{ |k, v| v }.reverse.to_h
— Marc-André Lafortune

4
실제로 해시보다 쌍의 배열을 얻는 것에 대해 동일한 경고가있는 hash.sort_by (& : last)와 같이 더 간단합니다.
— Gerry Gleason


14

이미 대답했지만 여전히. 코드를 다음과 같이 변경하십시오.

metrics.sort {|a1,a2| a2[1].to_i <=> a1[1].to_i }

도중에 문자열로 변환되거나 변환되지 않으면 작업이 수행됩니다.


9

그것은 내가보고있는 행동이 아닙니다.

irb(main):001:0> metrics = {"sitea.com" => 745, "siteb.com" => 9, "sitec.com" =>
 10 }
=> {"siteb.com"=>9, "sitec.com"=>10, "sitea.com"=>745}
irb(main):002:0> metrics.sort {|a1,a2| a2[1]<=>a1[1]}
=> [["sitea.com", 745], ["sitec.com", 10], ["siteb.com", 9]]

줄을 따라 어딘가에서 숫자가 문자열로 변환 될 수 있습니까? 게시하지 않은 코드가 더 있습니까?


아아, 내 코드의 결과가 문자열로 반환되는 것처럼 보입니다. 성가신 데이터 유형. :) 때로는 문제에 너무 가깝습니다. 감사.
— Dustin M.

1
예. 때때로 누군가 누군가 루비를 "untyped"라고 언급하는 것을 들었습니다. 아뇨, 확실히 입력되었습니다. 정적으로 입력되지 않았습니다. :)
— Jacob Mattison
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.