2009-12-23 6 views
0

사용자가 배열에있는 열의 순서를 정의했습니다. 루비에서 배열 정렬

order = [:col1, :col2, :col3] 

사용자 정의 열 테이블의 상태를 주문 이후

가 변경되어 칼럼의 현재리스트를 정렬하는 데 필요한 소정의 순서로 COLS

cols = [:col1, :col4, :col3, :col5] 

이다. 이 경우 정렬 된 열은이 두 가지 경우 중 하나처럼 보일 수 있습니다.

[:col2, :col3, :col4, :col5] 
[:col2, :col3, :col5, :col4] 

다음은 작동시키기위한 코드입니다. 더 좋은 방법이 있는지 궁금합니다.

#get rid of :col2 since it is not present in the cols listing 
sanitized_order = order - (order - cols) 

sorted_cols = sanitized_order + (cols - sanitized_order) 
+0

사양에 대해 다소 혼란 스럽습니다. 어떻게 알 수 있습니까? col4와 : col5는 순서의 일부가 아니기 때문에 목록 시작 부분에 (예를 들어) 가지 않습니다. 아니면 "주문에 없다면 끝까지 가야한다"는 규칙일까요? –

+0

열이 주문 목록에 정의되지 않은 경우 주문 열에 언급 된 열 뒤에 열을 넣으라는 메시지가 표시됩니다. 기본적으로 col4 및 : col5를 낮은 우선 순위에 넣습니다. – Roger

답변

2

무엇이 더 좋습니까? 당신은 이미 당신의 일을 아주 편하게하셨습니다.

1) 본인의 것과 같지만 읽을 수있는 행은 1 개입니다.

order = [:col1, :col2, :col3] 
cols = [:col1, :col4, :col3, :col5] 

sanitized_order = [] 

order.each do |column| 
    if cols.include?(column) then 
    sanitized_order << column 
    cols.delete(column) 
    end 
end 

cols.each do |remainingcolumn| 
    sanitized_order << remainingcolumn 
end 

puts sanitized_order 
0

여기에 또 다른입니다 : 여기

#order & cols -> provides unique items found in both 
#cols - order -> provides columns that are in cols but not order 
sorted_cols = (order & cols) + (cols - order) 

2)

사람이 논리를 볼 라인으로 라인을 따라 대신 테이블의 차이를 파악 할 수 있도록 더 많은 책처럼 읽는 방법 말로 할 수있는 방법 :

order = [:col1, :col2, :col3] 
cols = [:col3, :col2, :col5, :col4] 
sorted_order = cols.sort_by do |c| 
    if order.index(c) 
    [1, order.index(c)] 
    else 
    [2, cols.index(c)] 
    end 
end 
p sorted_order # => [:col2, :col3, :col5, :col4] 

다음은 작동 방식입니다. sort_by는 배열의 요소를 블록에 반환합니다. 블록은 다음과 비슷한 것을 반환해야합니다 (기술적으로는 < => 연산자에 응답하는 것). sort_by는 블록이 반환하는 결과에 대해 < => 연산자를 사용하여 배열의 순서를 결정합니다. 알다시피 => (우주선) 연산자는 두 요소를 취하는 이항 연산자입니다. 및 b. < b이면 -1을 반환합니다. a == b이면 0을 반환하고,> b이면 +1을 반환합니다.

배열은 < => 연산자에 놀랄만 한 방식으로 응답합니다. 왼쪽 배열의 요소는 오른쪽 배열의 요소와 차례로 비교되며 인덱스 0부터 시작하여 증가합니다. a [i] < => b [i]가! = 0이면 결과를 반환하지만 결과가 0이면 다음 요소를 검사합니다. 비교 된 마지막 요소 쌍이 0 (같음)이고 배열의 크기가 동일한 경우 배열은 같고 Array입니다. < =>는 0을 반환하고 그렇지 않으면 더 긴 배열이 더 큰 것으로 간주됩니다 (이 예제는 항상 같은 크기의 배열을 반환합니다).

따라서, 예를 들어 :

[2, 1] <=> [2, 2] == -1 
[2, 2] <=> [2, 2] == 0 
[2, 3] <=> [2, 2] == +1 
[1, 2] <=> [2, 1] == +1 

그래서하는 sort_by 내부 우리 배열 나타내는 1 차, 2 차, 3 차 등의 정렬 순서의 요소를 사용할 수있다. a [0]은 기본 정렬 순서이고 [1]은 보조 정렬 순서입니다.

고객이 지정한 모든 열이 먼저 와야합니다. 따라서 각 열에 대해 고객 지정 순서 (order)의 색인을 찾으십시오. 그것이 숫자를 반환하면 고객이 해당 열을 지정했으며 고객 지정 목록에서 색인을 알고 있음을 알 수 있습니다. 고객이 지정한 열이 먼저 오기를 원하기 때문에 기본 정렬 순서는 1입니다. 고객이 열을 지정한 순서를 알려주기 때문에 2 차 정렬 순서가 색인입니다.

우리가 순서 배열에서 열을 찾지 못하면 (즉, order.index (c)가 nil을 반환하는 경우) 주 정렬 순서로 2가되고 마스터 열 목록에 색인 (cols)를 보조 정렬 순서로 사용합니다. 그런 식으로 고객이 지정하지 않은 모든 열은 마지막이지만 순서대로 래스터 열 목록에 지정됩니다.

+0

차가워졌습니다. 이것은 효과가있다. 그러나 나는 그것이 그렇게 명백하지 않다라고 생각한다. – Roger

+0

설명을 추가했습니다. 도움이되기를 바랍니다. –