2016-08-18 3 views
0

을 예상대로 작동하지루비 문자 및 숫자 정렬 다음과 같은 배열을 지정해,

=> ["A1", "A2", "A6", "A8", "B3", "B4", "B5", "B8", "B10", "B12"] 

을 다음 (바닐라) 종류를 사용하여, 나는 얻을 :

irb(main):2557:0> y.sort{|a,b| puts "%s <=> %s = %s\n" % [a, b, a <=> b]; a <=> b} 
A1 <=> A8 = -1 
A8 <=> B8 = -1 
A2 <=> A8 = -1 
B5 <=> A8 = 1 
B4 <=> A8 = 1 
B3 <=> A8 = 1 
B10 <=> A8 = 1 
B12 <=> A8 = 1 
A6 <=> A8 = -1 
A1 <=> A2 = -1 
A2 <=> A6 = -1 
B12 <=> B3 = -1 
B3 <=> B8 = -1 
B5 <=> B3 = 1 
B4 <=> B3 = 1 
B10 <=> B3 = -1 # this appears to be wrong, looks like 1 is being compared, not 10. 
B12 <=> B10 = 1 
B5 <=> B4 = 1 
B4 <=> B8 = -1 
B5 <=> B8 = -1 
=> ["A1", "A2", "A6", "A8", "B10", "B12", "B3", "B4", "B5", "B8"] 

... 분명히 내가 원하는 바가 아닙니다. 나는 먼저 알파를 분리하고 숫자를 정렬하려고 시도 할 수 있다는 것을 알고 있지만, 그렇게하지 않아도되는 것처럼 보입니다.

가능한 큰주의해야 할 점은 우리가 루비를 사용하여 붙어있어 지금 :(그러나 심지어 루비 2.0.0이 같은 일을하고 위해 1.8.7 내가 여기 실종 무엇

제안을

+3

첫 번째 직감은 올바른 것입니다. 이것들은 문자열이기 때문에 사전 식으로 정렬 될 것입니다. 번호를 주문의 요소로 고려하려면 번호와 문자를 분리하고 정렬 할 때 자신의 의지를 사용해야합니다. – Makoto

+2

왜 * 문자열 * "B12"가 * 문자열 * "B2"앞에 정렬 될지 궁금합니다. 이것은 루비가 문자열을 정렬하는 방법이 아니라, * 모든 것이 문자열을 정렬하는 방법입니다. – meagar

+0

당신은'y.sort_by {| s | [ "A1", "A2", "A6", "A8", "B3", "B4", "B5", " "B8", "B10", "B12"]'. 루비가 배열을 정렬하는 방법은 [Array # <=>] (http://ruby-doc.org/core-2.3.0/Array.html#method-i-3C-3D-3E)을 참조하십시오. –

답변

1

문자열을 정렬하고 있습니다. 문자열은 숫자가 아닌 문자열처럼 정렬됩니다. 같은 숫자를 정렬하려면 문자열이 아닌 숫자를 정렬해야합니다. 문자열 'B10'은 사전 프로그래밍 언어로는 'B3'보다 작습니다. 이는 프로그래밍에 고유하지 않은 루비에 국한된 것이 아니며 사전 편집, 데이터베이스, 어휘집, 사전, 전화 번호부,

문자열을 숫자 및 비 숫자 구성 요소로 분할하고 숫자 구성 요소를 숫자로 변환해야합니다. 배열 정렬은 사전 편집이므로 올바른 정렬을 완료합니다.

y.sort_by {|s| # use `sort_by` for a keyed sort, not `sort` 
    s. 
    split(/(\d+)/). # split numeric parts from non-numeric 
    map {|s| # the below parses numeric parts as decimals, ignores the rest 
     begin Integer(s, 10); rescue ArgumentError; s end }} 
#=> ["A1", "A2", "A6", "A8", "B3", "B4", "B5", "B8", "B10", "B12"] 
-1

을 수행합니다.? 표준 문자 값 기반 정렬이 아닌 자연 또는 사전 정렬이 필요합니다. 이러한 보석과 같은 것이 시작점이 될 것입니다 :

인간은 "A2"와 같은 문자열을 "A"로 처리합니다. 숫자 2, 문자열 부분에 대한 문자열 정렬 및 숫자 PA에 대한 숫자 정렬을 사용하여 정렬 rt. 표준 sort()은 문자가 무엇인지에 관계없이 문자열을 일련의 문자로 처리하는 문자 값 정렬을 사용합니다. 따라서 sort()의 경우 'A10'과 'A2'는 [ 'A', '1', '0'] 및 [ 'A', 2 ']와 유사합니다.'1 '은'2 ' 그 순서를 바꾸지 않으면 "A10"이 "A2"앞에 정렬됩니다. 인간의 경우 동일한 문자열이 2와 같이 [ "A", 10] 및 [ "A", 2], 10 종류처럼 보이므로 반대 결과를 얻습니다. 이 문자열은 숫자 값을 고정 너비로 ​​만들고 왼쪽에 0을 채워서 공백을 넣지 않아 문자 값 기반 sort()이 예상 결과를 만들어 "A2"가 "A02"로 바뀌도록 조작 할 수 있습니다. "012"를 사용하여 "A10"앞에 정렬하십시오.

+0

이 방법은 실제로 문제를 해결하지만 정렬이 작동하지 않는 이유는 설명하지 않습니다. 매우 흥미있다. – Jim

+1

숫자 값은 문자열 표현의 문자 별 정렬과 다르게 정렬됩니다. 문자 값 정렬은 예를 들어 작동하지 않습니다. "1"의 문자 값이 '2'보다 작고 "A10"이 "A2"보다 먼저 정렬되기 때문에 "A10"및 "A2"가됩니다. OTOH라는 자연적인 분류는 "A2"를 "A02"또는 [ "A", 2] ("A"다음에 숫자 2로 처리하는 방식)와 동일하게 해석합니다. –

+1

NB : 위의 이유는 문자 파일 정렬이 숫자 정렬 결과와 일치하도록 고정 폭 고정 소수점 위치 제로 패딩 된 필드에서 데이터 파일에 자주 오른쪽 정렬되는 숫자를 보는 이유입니다. –