Ruby에서 객체 속성별로 객체 배열을 정렬합니까?


128

Ruby on Rails에 객체 배열이 있습니다. 객체의 속성으로 배열을 정렬하고 싶습니다. 가능할까요?

답변:


222

대신 sort_by를 사용하는 것이 좋습니다.

objects.sort_by {|obj| obj.attribute}

특히 속성을 계산할 수있는 경우.

또는 더 간결한 접근 방식 :

objects.sort_by(&:attribute)

81
또는 속기 버전 :objects.sort_by(&:attribute)
Nikola

3
더 짧은 objects.sort_by & : 속성
jasin_89

1
대문자와 소문자를 따로 분류하는 데 문제가있는 경우 다음을 사용할 수 있습니다.objects.sort_by { |obj| obj.attribute.downcase }
campeterson

1
이것이 sort!(예 : 속도 등) 과 어떻게 비교되는지 아십니까?
Joshua Pinter 2015


35

예, Array#sort!이것을 사용 하는 것은 쉽습니다.

myarray.sort! { |a, b|  a.attribute <=> b.attribute }

Thnx 친구이지만 저에게 효과가 없었습니다. 객체의 속성 중 하나가 created_at입니다. 이 필드로 정렬하고 싶습니다. 그래서 @ comm_bytes.sort를했습니다! {| a, b | a.created_at <=> b.created_at}하지만 운이 없으시면 도와 드릴 수 있습니다 .... ??

4
@created_at 속성에 액세스하는 created_at 메서드가 있습니까? @created_at는 어떤 종류의 개체입니까? 정의 <=>합니까? 어떤 종류의 오류가 발생합니까? 등, 광고 메스꺼움. 즉, "하지만 나에게는 운이 없다"보다 더 자세한 정보가 필요합니다.
rampion

"!"없이 myarray = myarray.sort {...}를 수행하면 작동합니다.
DoruChidean

@Doru 예, 그것도 작동하지만 왜 그렇게 하시겠습니까? 덜 직접적이고 덜 효율적입니다. sort원본을 보존하고 결과를 다른 개체에 할당하려는 경우 사용 합니다. 그렇지 않으면 내부 변형 sort!. 실제로 원본 객체를 복사 한 후 내부적으로 sort호출 sort!합니다.
Konrad Rudolph

1
@Doru 코드 어딘가에 오류가있을 것입니다. 100 % sort!제대로 작동 할 것이라고 보장 할 수 있으며, 항상 (!) 작성한 것과 동일한 작업을 수행합니다.
Konrad Rudolph

27

오름차순 :

objects_array.sort! { |a, b|  a.attribute <=> b.attribute }

또는

objects_array.sort_by{ |obj| obj.attribute }

내림차순 :

objects_array.sort! { |a, b|  b.attribute <=> a.attribute }

또는

objects_array.sort_by{ |obj| obj.attribute }.reverse

20

두 속성으로 정렬해야하는 경우, 첫 번째 속성이 두 번째 속성보다 더 중요합니다 (첫 번째 인수가 동일한 경우에만 두 번째 인수를 고려함을 의미 함), 다음과 같이 할 수 있습니다.

myarray.sort{ |a,b| (a.attr1 == b.attr1) ? a.attr2 <=> b.attr2 : a.attr1 <=> b.attr1 }

또는 배열 배열의 경우

myarray.sort{ |a,b| (a[0] == b[0]) ? a[1] <=> b[1] : a[0] <=> b[0] }

14

<=> 메서드를 재정 의하여 모든 클래스를 정렬 가능하게 만들 수 있습니다.

class Person

  attr_accessor :first_name, :last_name

  def initialize(first_name, last_name)
    @first_name = first_name
    @last_name = last_name
  end

  def <=>(other)
    @last_name + @first_name <=> other.last_name + other.first_name
  end

end

이제 Person 객체의 배열을 last_name에서 정렬 할 수 있습니다.

ar = [Person.new("Eric", "Cunningham"), Person.new("Homer", "Allen")]

puts ar  # => [ "Eric Cunningham", "Homer Allen"]  (Person objects!)

ar.sort!

puts ar  # => [ "Homer Allen", "Eric Cunningham" ]

10

위에 게시 된대로 Array # sort가 잘 작동합니다.

myarray.sort! { |a, b|  a.attribute <=> b.attribute }

하지만 <=>해당 속성에 대해 연산자가 구현 되었는지 확인해야 합니다. Ruby 기본 데이터 유형 인 경우 문제가되지 않습니다. 그렇지 않으면 a <b이면 -1을, 같으면 0을, a> b이면 1을 반환하는 구현을 작성하십시오.


10

더 우아한 objects.sort_by(&:attribute), 당신은 .reverse순서를 전환해야하는 경우에 추가 할 수 있습니다 .



-2
@model_name.sort! { |a,b| a.attribute <=> b.attribute }

2
2009 년에 게시 된 동일한 답변이 많이 있습니다. 다른 답변을 추가 할 필요가 없습니다.
interjay

2
sort직접 비교할 수없는 개체를 정렬 할 때는 사용하지 마십시오 . 속성에 액세스해야하거나 비교할 값을 얻기 위해 계산을 수행해야하는 경우 사용하십시오 sort_by. 훨씬 빠를 것입니다.
틴 남자
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.