Ruby에서 배열의 일부를 반환하는 방법은 무엇입니까?


125

Python의 목록을 사용하면 다음 코드를 사용하여 일부를 반환 할 수 있습니다.

foo = [1,2,3,4,5,6]
bar = [10,20,30,40,50,60]
half = len(foo) / 2
foobar = foo[:half] + bar[half:]

Ruby는 모든 것을 배열로 처리하기 때문에 이와 비슷한 것이 있는지 궁금합니다.

답변:


192

예, Ruby는 Python과 매우 유사한 배열 분할 구문을 가지고 있습니다. ri배열 인덱스 방법에 대한 문서 는 다음과 같습니다 .

--------------------------------------------------------------- Array#[]
     array[index]                -> obj      or nil
     array[start, length]        -> an_array or nil
     array[range]                -> an_array or nil
     array.slice(index)          -> obj      or nil
     array.slice(start, length)  -> an_array or nil
     array.slice(range)          -> an_array or nil
------------------------------------------------------------------------
     Element Reference---Returns the element at index, or returns a 
     subarray starting at start and continuing for length elements, or 
     returns a subarray specified by range. Negative indices count 
     backward from the end of the array (-1 is the last element). 
     Returns nil if the index (or starting index) are out of range.

        a = [ "a", "b", "c", "d", "e" ]
        a[2] +  a[0] + a[1]    #=> "cab"
        a[6]                   #=> nil
        a[1, 2]                #=> [ "b", "c" ]
        a[1..3]                #=> [ "b", "c", "d" ]
        a[4..7]                #=> [ "e" ]
        a[6..10]               #=> nil
        a[-3, 3]               #=> [ "c", "d", "e" ]
        # special cases
        a[5]                   #=> nil
        a[6, 1]                #=> nil
        a[5, 1]                #=> []
        a[5..10]               #=> []

5
a [5, 1]이 a [6, 1]과 다른 이유는 무엇입니까?
dertoni


25
a[2..-1]세 번째 요소에서 마지막 요소로 이동합니다. a[2...-1]세 번째 요소에서 두 번째 마지막 요소까지 가져옵니다.
영리 프로그래머

1
@Rafeh 환호,이 정크 작품, -1 트릭 어떻게했는지 궁금
벤 싱클레어

@CleverProgrammer 구문은 허용되는 답변보다 Python에 훨씬 더 가깝습니다. 저는 Ruby를 좋아하지만 Python의 구문이 더 짧고 명확하다고 말해야합니다. 보너스로,이 단계를 지정할 수 있습니다 :range(10)[:5:-1]
에릭 Duminil


17

이를 위해 slice () 를 사용할 수 있습니다 .

>> foo = [1,2,3,4,5,6]
=> [1, 2, 3, 4, 5, 6]
>> bar = [10,20,30,40,50,60]
=> [10, 20, 30, 40, 50, 60]
>> half = foo.length / 2
=> 3
>> foobar = foo.slice(0, half) + bar.slice(half, foo.length)
=> [1, 2, 3, 40, 50, 60]

그건 그렇고, 내가 아는 한, 파이썬 "목록"은 동적으로 증가하는 배열로 효율적으로 구현됩니다. 시작 부분의 삽입은 O (n), 끝 부분의 삽입은 분할 O (1), 랜덤 액세스는 O (1)입니다.


두 번째 슬라이스에서 막대 배열을 사용한다는 뜻입니까?
Samuel

참고 : slice!()배열을 제자리에서 수정하지 않고 "인덱스 (선택적으로 최대 길이 요소) 또는 범위에 의해 제공된 요소를 삭제합니다." 당 ruby-doc.org/core-2.2.3/Array.html#method-i-slice-21
여호수아 핀터

7

또 다른 방법은 범위 방법을 사용하는 것입니다.

foo = [1,2,3,4,5,6]
bar = [10,20,30,40,50,60]
a = foo[0...3]
b = bar[3...6]

print a + b 
=> [1, 2, 3, 40, 50 , 60]

3

Ruby 2.6 시작 / 무제한 범위

(..1)
# or
(...1)

(1..)
# or
(1...)

[1,2,3,4,5,6][..3]
=> [1, 2, 3, 4]

[1,2,3,4,5,6][...3]
 => [1, 2, 3]

ROLES = %w[superadmin manager admin contact user]
ROLES[ROLES.index('admin')..]
=> ["admin", "contact", "user"]

2

나는 이것에 대한 범위를 좋아한다.

def first_half(list)
  list[0...(list.length / 2)]
end

def last_half(list)
  list[(list.length / 2)..list.length]
end

그러나 엔드 포인트가 범위에 포함되는지 여부에 대해 매우주의하십시오. 이것은 중간을 깰 위치를 선택해야하는 홀수 길이 목록에서 중요합니다. 그렇지 않으면 중간 요소를 두 번 계산하게됩니다.

위의 예는 지속적으로 중간 요소를 마지막 절반에 배치합니다.


(list.length / 2.0).ceil필요한 경우 전반부에 중간 요소를 일관되게 배치하는 데 사용할 수 있습니다 .
소라시
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.