Ruby <=> (우주선) 연산자는 무엇입니까?


262

루비 <=>(우주선) 연산자 란 무엇입니까 ? 운영자가 다른 언어로 구현 되었습니까?


1
이제 배열을 비교하는 것은 어떻습니까? 이 책에서 "요소별로 요소를 비교하고, 같으면 0을, 덜 작 으면 -1, 더 크면 1을 반환하지만, [1,3,2] <=> [2,2,2]어떻습니까?
SF.

3
@SF는 사람들이 배열을 비교할 때 사전과 같이 사전을 비교하는 것을 의미합니다 (예 : 첫 번째 요소가 다르기 때문에 사전 (예 : [1,3,2] <[2,2,2])). Matlab에서 fe는 드물게 배열 비교는 요소 당 결과 배열을 반환합니다. 이 경우 : [-1, 1, 0].
liori

nil 요소를 포함하는 배열은 nil 이전의 요소가 다르면 비교 가능하며, nil을 non-nil과 비교해야하는 경우에는 비교할 수 없습니다. 즉 [1, nil] <=> [2, 3] => -1이지만 [1, nil] <=> [1, 3] => nil입니다. 이것은 기본적으로 짜증납니다.
cliffordheath

비교 배열이 좋아하는 때 [1,nil] <=> [1,3]당신이 얻을 nil때까지 차례로 각 요소를 비교하기 때문에 알고리즘의 일관성의 <=>결과가 아닙니다 0. 루비가이 예제에서보다 작거나 큰 것을 선언 할 수있는 방법은 없습니다. 비교를 간단히 할 수 없기 때문입니다. 은 nil"동일하지 않은"으로 처리되어야한다. 당신이 데이터에 대해 뭔가를 알고, 예를 들면 치료를 원하는 경우 nil0, 루비는 쉬운 것이 있습니다.
lilole

답변:


359

펄은 그것을 처음 사용한 언어 일 것입니다. Groovy는이를 지원하는 또 다른 언어입니다. 기본적으로 반환하는 대신 1( true) 또는 0( false) 인수가 동일하거나 동일하지 여부에 따라 우주선 연산자 반환 1, 0또는 −1오른쪽 인자에 대하여 왼쪽 인자의 값에 따라.

a <=> b :=
  if a < b then return -1
  if a = b then return  0
  if a > b then return  1
  if a and b are not comparable then return nil

배열을 정렬하는 데 유용합니다.


27
바로 그거죠. 나는 그것을 Java의 Comparable의 매우 우아한 버전이라고 생각합니다.
Mike Reedell

12
c #의 아날로그는 IComparable.CompareTo
Sergey Mirvoda

1
실제로 나는 음수 또는 양수 값을 반환 할 수 있다고 생각합니다. 0은 여전히 ​​평등을 의미합니다.
superluminary

1
@superluminary C의 strcmp 함수와 달리 x <=> y는 x와 y를 비교할 수없는 경우 (루비 및 AFAIK를 사용하는 다른 언어에서) -1, 0, 1 또는 nil 만 반환하도록 특별히 설계되었습니다. 따라서 Ruby의 Comparable 믹스 인과 같이 운영자에게 과부하가 걸리기 쉽습니다. 연산자가 가장 많이 시작된 Perl에서는 주로 "정렬 BLOCK LIST"구문을 단순화하는 데 사용되었습니다. BLOCK은 목록 항목을 정렬하는 방법에 따라 양수, 음수 또는 0을 리턴 할 수있는 서브 루틴입니다. 우주선에서 사용하기 편리하다.
TonyArra

2
참고 비해 두 개체를 비교하지 않은 경우, 당신은 전무 얻을
gamov

70

우주선 방법은 자신의 클래스에서 정의하고 Comparable 모듈을 포함 할 때 유용 합니다 . 그러면 수업 >, < , >=, <=, ==, and between?에서 무료로 메소드를 받습니다 .

class Card
  include Comparable
  attr_reader :value

  def initialize(value)
    @value = value
  end

  def <=> (other) #1 if self>other; 0 if self==other; -1 if self<other
    self.value <=> other.value
  end

end

a = Card.new(7)
b = Card.new(10)
c = Card.new(8)

puts a > b # false
puts c.between?(a,b) # true

# Array#sort uses <=> :
p [a,b,c].sort # [#<Card:0x0000000242d298 @value=7>, #<Card:0x0000000242d248 @value=8>, #<Card:0x0000000242d270 @value=10>]

20

일반적인 비교 연산자입니다. 수신자가 인수보다 작거나 같거나 큰지 여부에 따라 -1, 0 또는 +1을 리턴합니다.


18

간단한 예를 들어 설명하겠습니다

  1. [1,3,2] <=> [2,2,2]

    Ruby는 두 배열의 각 요소를 왼쪽에서 비교하기 시작합니다. 1왼쪽 배열 2의 경우 오른쪽 배열 보다 작습니다 . 따라서 왼쪽 배열은 오른쪽 배열보다 작습니다. 출력은입니다 -1.

  2. [2,3,2] <=> [2,2,2]

    위와 같이 먼저 동일한 첫 번째 요소를 비교 한 다음 두 번째 요소를 비교합니다.이 경우 왼쪽 배열의 두 번째 요소는 더 커서 출력은 1입니다.


각 배열의 첫 번째 왼쪽 요소를 비교하거나 다른 요소도 계속 비교합니까? 좋은 설명
Kick Buttowski

1
@KickButtowski는 다른 숫자를 찾지 않으면 다른 요소를 계속 비교합니다.
Anil Maurya

5

이 연산자는 정수 표현식에 대한 비교를 줄이므로 여러 열 / 속성을 기준으로 오름차순 또는 내림차순으로 정렬하는 가장 일반적인 목적을 제공합니다.

예를 들어 객체 배열이 있으면 다음과 같이 할 수 있습니다.

# `sort!` modifies array in place, avoids duplicating if it's large...

# Sort by zip code, ascending
my_objects.sort! { |a, b| a.zip <=> b.zip }

# Sort by zip code, descending
my_objects.sort! { |a, b| b.zip <=> a.zip }
# ...same as...
my_objects.sort! { |a, b| -1 * (a.zip <=> b.zip) }

# Sort by last name, then first
my_objects.sort! { |a, b| 2 * (a.last <=> b.last) + (a.first <=> b.first) }

# Sort by zip, then age descending, then last name, then first
# [Notice powers of 2 make it work for > 2 columns.]
my_objects.sort! do |a, b|
      8 * (a.zip   <=> b.zip) +
     -4 * (a.age   <=> b.age) +
      2 * (a.last  <=> b.last) +
          (a.first <=> b.first)
end

이 기본 패턴은 각각의 오름차순 / 내림차순 순열에서 여러 열을 기준으로 정렬하도록 일반화 할 수 있습니다.


좋은 예는, 마지막 예가 예상대로 작동하지 않는다는 것입니다. 요인은 내림차순으로 2의 거듭 제곱 (예 : 8, -4, 2, 1)이어야합니다. 예를 들어 "연령 + 성"이 "zip보다 많은 수" "...
Elmar Zander

나는 그 숫자가 당신이 생각하는 것을 의미한다고 생각하지 않습니다. 각 요소는 -1, 0 또는 1의 부호를 곱합니다. 2의 거듭 제곱은 여기서 중요하지 않습니다. -3 * (a.age <=> b.age)는 3 * (b.age <=> a.age)와 정확히 동일합니다. 결과의 표시는 그것이 오름차순 또는 디스크를 만드는 것입니다.
lilole

아니, 그것은 중요하다. 지퍼 팩터는 다른 모든 팩터의 (절대) 합계보다 커야하고, 연령 팩터는 마지막 및 첫 번째 팩터 등의 (절대) 합계보다 커야합니다. 그리고 숫자의 가장 작은 순서 두 가지의 힘의 순서입니다 ... 그리고 당신은 신중하게 내 의견을 읽으면 BTW, 당신은 내가 빼기 기호 ... 포함되어 있음을 알 것이다 그 어떤 충족
엘마 잰더를

1
좋아, 어쩌면 좀 더 자세히 설명 할 것입니다 : 요인 (4, -3,2,1)과 우주선 op (1,1, -1, -1)의 결과로 가중 합은 -2이지만 긍정적이어야합니다! 그렇지 않으면 더 큰 zip이 더 작은 zip보다 먼저 나옵니다. 요인 (8, -4,2,1)에서는 발생하지 않습니다.
Elmar Zander

1
아, 이제 2 열 이상 정렬하면 2의 거듭 제곱이 필요합니다. 이 문제를 해결하는 데 도움을 주셔서 감사합니다. 3 개 이상의 열 정렬이 잘못되면 죄송합니다.
lilole

-2

무엇입니까 <=> ( '우주선'연산자)

운영자를 소개RFC 에 따르면 $ a <=>$ b

 -  0 if $a == $b
 - -1 if $a < $b
 -  1 if $a > $b

 - Return 0 if values on either side are equal
 - Return 1 if value on the left is greater
 - Return -1 if the value on the right is greater

예:

//Comparing Integers

echo 1 <=> 1; //ouputs 0
echo 3 <=> 4; //outputs -1
echo 4 <=> 3; //outputs 1

//String Comparison

echo "x" <=> "x"; // 0
echo "x" <=> "y"; //-1
echo "y" <=> "x"; //1

더:

// Integers
echo 1 <=> 1; // 0
echo 1 <=> 2; // -1
echo 2 <=> 1; // 1

// Floats
echo 1.5 <=> 1.5; // 0
echo 1.5 <=> 2.5; // -1
echo 2.5 <=> 1.5; // 1

// Strings
echo "a" <=> "a"; // 0
echo "a" <=> "b"; // -1
echo "b" <=> "a"; // 1

echo "a" <=> "aa"; // -1
echo "zz" <=> "aa"; // 1

// Arrays
echo [] <=> []; // 0
echo [1, 2, 3] <=> [1, 2, 3]; // 0
echo [1, 2, 3] <=> []; // 1
echo [1, 2, 3] <=> [1, 2, 1]; // 1
echo [1, 2, 3] <=> [1, 2, 4]; // -1

// Objects
$a = (object) ["a" => "b"]; 
$b = (object) ["a" => "b"]; 
echo $a <=> $b; // 0
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.