Ruby 배열의 마지막 요소를 제외한 모든 요소


139

루비 배열이 있다고 가정 해 봅시다.

a = [1, 2, 3, 4]

첫 번째 항목을 제외한 모든 것을 원하면 쓸 수 있습니다 a.drop(1). 그래도 마지막 항목을 제외한 모든 것을 원한다면 이 방법 만 생각할 수 있습니다

a[0..-2]   # or
a[0...-1]

그러나 이것들 중 어느 것도 사용하는 것만 큼 깨끗한 것처럼 보이지 않습니다 drop. 내가 놓친 다른 내장 방법은 무엇입니까?


globalnerdy.com/2008/07/10/… 에 따르면 드롭은 루비 1.8.6이 아니라 루비 1.9입니다.
Andrew Grimm

성능은 어떻습니까?.이 답변을 반복해서 1000 번 반복해서 사용한다면 어떤 것이 이길까요?
Ninad

다시 말해, 어떤 솔루션이 후드 아래에서 어레이를 통과하지 않습니까?
Ninad

다른 방법으로, a-([a.size])
John

답변:


128

혹시...

a = t               # => [1, 2, 3, 4]
a.first a.size - 1  # => [1, 2, 3]

또는

a.take 3

또는

a.first 3

또는

a.pop

마지막을 반환하고 배열 앞에 모든 것을 남겨 둡니다.

또는 저녁 식사를 위해 컴퓨터를 작동 시키십시오 .

a.reverse.drop(1).reverse

또는

class Array
  def clip n=1
    take size - n
  end
end
a          # => [1, 2, 3, 4]
a.clip     # => [1, 2, 3]
a = a + a  # => [1, 2, 3, 4, 1, 2, 3, 4]
a.clip 2   # => [1, 2, 3, 4, 1, 2]

5
Array나에게 가장 좋은 방법 인 것처럼 방법을 추가 하십시오. 대부분의 프로젝트 core_ext.rb는 이와 같은 확장자가 거의없는 파일로 끝납니다 . 일부 라이브러리는 실제로 다음 과 같은 모든 확장 ActiveSupport입니다.
rfunduk

흥미 롭습니다. 그것이 얼마나 흔한 지 궁금했습니다. 사람들은시 모드에 대해 어떻게 생각합니까?
DigitalRoss

5
clip누군가이 방법을 Ruby 커뮤니티에 어떻게 제출 합니까? 나는 이것이 실제로 거기에 있어야한다고 생각하며 원숭이 패치는 잘못된 것 입니다.
Droogans 2013

7
나는 a.reverse.drop(1).reverse전략을 좋아한다 . ;-)
Alex

92

호기심에서, 당신은 왜 안 좋아 a[0...-1]합니까? 배열 조각을 얻으려고하므로 조각 연산자는 관용적 인 선택처럼 보입니다.

그러나 이것을 모든 곳에서 호출 해야하는 경우 DigitalRoss가 제안한 것처럼 항상 더 친숙한 이름의 메소드를 Array 클래스에 추가 할 수 있습니다. 아마도 이것처럼 :

class Array
    def drop_last
        self[0...-1]
    end
end

낙하가 매우 깨끗할 때 많은 혼란처럼 보입니다. 큰 문제는 아니지만, 정확히 옳다는 것을 한 눈에 확인하기는 어렵습니다. drop_last
Peter

나는 .length를 사용하는 것보다 훨씬 더 -1을 사용하는 것을 좋아합니다.
Will Nathan

궁금합니다. 그 세 번째 의미는 무엇 .입니까?
Joshua Pinter

5
...는 마지막 항목을 포함하지 않음을 의미합니다. -1은 마지막 항목입니다. 두 개의 점을 사용하면 마지막 항목이 포함되고 세 개의 점이 마지막 항목을 포함하지 않습니다.
ckim

배열의 꼬리를 얻기 위해 슬라이스 연산자를 사용하는 것을주의하십시오 : 반환 할 수 있습니다 nil: [][1..-1]-> nil, [][0...-1]->[]
Michael

57

또 다른 멋진 트릭

>> *a, b = [1,2,3]
=> [1, 2, 3]
>> a
=> [1, 2]
>> b
=> 3

니스, 루비에게 이런 사실이 있다는 것을 몰랐다. 그래서 a, *b = [1,2,3]우리가 클래식 자동차 / CDR 방식으로 배열을 살펴 보자 것입니다.
Nobbynob Littlun

솔직히, 난 그 의견을 작성 기억하지 않는다 : D는 ... 지금 삭제
페트르 벨라에게

Soooo 간단하고 좋은. THX
microspino

43

pop()배열 에서 작업 을 수행 하려고하지만 (마지막 항목이 삭제되는 경우) 팝 된 요소 대신 배열을 얻는 데 관심이 있다면 다음을 사용할 수 있습니다 tap(&:pop).

> arr = [1, 2, 3, 4, 5]
> arr.pop
=> 5
> arr
=> [1, 2, 3, 4]
> arr.tap(&:pop)
=> [1, 2, 3]

이 답변은 의미 적으로이 사용자에게 가장 적합한 답변입니다. 미러 작업이 진행 중이며 해석하기 쉽고 간결한 단어를 사용합니다.
Jerome

2
매끄러운 루비입니다.
emptywalls

38

나는 이렇게한다 :

my_array[0..-2]

2
이것은 환상적으로 작동합니다. 왜 훨씬 더 복잡한 답변이 있는지 혼란 스럽습니다. 이것이 새로운 루비 추가입니까?
Joshua Pinter

@JoshuaPinter 처음부터 존재 합니다 . 나는 그것이 최선의 접근법이라는 것에 동의합니다.
Julien

23

예를 들어 드롭 방법 자체를 보강하는 것은 어떻습니까?

class Array
  def drop(n)
    n < 0 ? self[0...n] : super
  end
end

그런 다음 음수 크기를 사용하여 끝에서 요소를 제거 할 수 있습니다.

[1, 2, 3, 4].drop(-1) #=> [1, 2, 3]
[1, 2, 3, 4].drop(-2) #=> [1, 2]

19

a[0...-1]가장 좋은 방법 같습니다. 배열 슬라이싱 구문은 정확히이 목적으로 만들어졌습니다 ...

또는 배열을 수정하는 것이 마음에 들지 않으면 a.pop다음을 호출하면됩니다 .

>> a = [1, 2, 3, 4]
>> a.pop
>> a
=> [1, 2, 3]

나중에 사용할 수 있도록 마지막 요소를 변수에 할당 할 수도 있습니다.b = a.pop
Viktor Fonic

12

한 줄에서 마지막 요소를 제거하고 나머지는 반환합니다.

[1, 2, 4, 5, 6].reverse.drop(1).reverse

심각하게 생각,

[1,2,3,4][0..-2]
#=> [1,2,3]

11

이게 방법이야:

[1,2,3,4,5][0..-1-1]

그러나 이것이 어떻게 작동하는지 설명합시다.

a = [1,2,3,4,5]

다음 예제는 0 위치에서 마지막 위치까지 모든 레코드를 반환합니다.

a[0..-1]
=> [1, 2, 3, 4, 5]

다음 예제는 1 위치에서 마지막 레코드 반환합니다.

a[1..-1]
=> [2, 3, 4, 5]

그리고 여기에 필요한 것이 있습니다. 다음 예제는 0 위치에서 last-1 로 레코드 반환합니다.

a[0..-1-1]
=> [1, 2, 3, 4]

1
-2대신 쓸 수 있습니다 -1-1.
bfontaine

당신은 할 수있다 a[0...-1](3 점을 알)과 같은 결과를 얻을 a[0..-1-1]세 번째 점은 끝 요소를 제외 그것을 알려주기 때문에. 자세한 내용은 이것을 참조하십시오.
Julien

7

"취하기"를 해 보셨습니까

a.take(3) 

6
일반적으로 이것은 다음과 같습니다 a.take(a.size - 1). 예,이 옵션을 고려했습니다.
Peter

2

답변 : a.τwτ , 그러나 Pyper를 먼저 설치해야합니다 ...

Pyper는 소개 : 마 당신은 Lisp 다운을 알고 carcdr배열의 "처음"과 "휴식"을 반환? 귀하와 같은 요구에 부응하기 위해이 Lispy 메커니즘을 확장했습니다. 이라고 pyper하고 2nd, 3rd, 3d, 3d에서 쉬고 마지막 등을 제외한 모든 것에 액세스 할 수 있습니다. caar, cadr, cdadar등 리스프 공지 :

# First, gem install pyper
require 'pyper'
include Pyper
a = %w/lorem ipsum dolor sit amet/
# To avoid confusion with other methods, and also because it resembles a rain gutter,
# Greek letter τ is used to delimit Pyper methods:
aaτ #=> "lorem"
adτ #=> ["ipsum", "dolor", "sit", "amet"]
abτ #=> "ipsum"
aeτ #=> ["dolor", "sit", "amet"]
acτ #=> "dolor" (3rd)
azτ #=> "amet" (last)
ayτ #=> "sit" (2nd from the end)
axτ #=> "dolor" (3rd from the end)

마지막으로 귀하의 질문에 대한 답변 :

awτ #=> ["lorem", "ipsum", "dolor", "sit"] (all except last)

더 있습니다 :

auτ #=> ["lorem", "ipsum", "dolor"] (all except last 2)
a1τ #=> ["lorem", "ipsum"] (first 2)
a8τ #=> (last 2)
a7τ #=> (last 3)

구성 :

awydτ #=> "olor" (all except 1st letter of the last word of all-except-last array)

이 단지보다 더 많은 명령 문자도 있습니다 a..f, u..z그리고 0..9특히, m지도를 의미합니다 :

awmbτ #=> ["o", "p", "o", "i"] (second letters of all-except-last array)

그러나 다른 명령 문자는 너무 뜨겁고 현재 사용하기가 쉽지 않습니다.


1
나는 이것을 4 월 1 일에 읽고있다. 그래서 나는 그것이 장난이었다라고 생각했다. .. 아니. 루비에게 이런 것들이 존재하는지 전혀 몰랐습니다. :)
Joshua Pinter

1

이것은 원본의 마지막 요소를 제외한 새로운 배열을 만듭니다.

ary2 = ary.dup
ary2.pop

다른 사람들은 #pop을 사용하도록 제안했습니다. 배열을 제자리에서 수정해도 괜찮습니다. 그래도 문제가 없다면이 예제와 같이 먼저 배열을 dup하십시오.


1
배열을 수정하는 것이 괜찮다면 #pop 사용을 제안한 사람들도 있습니다. 그래도 문제가 없다면이 예제와 같이 먼저 배열을 dup하십시오.
alegscogs

이것은 중요한 의견입니다. 답변에 추가 할 수도 있습니다. #pop에는 뱅 (!)이 없기 때문에 원래 배열을 수정하면 사람들을 벗어날 수 있습니다.
mjnissim

배열이 큰 경우 비효율적입니다.
juliangonzalez

1

나는 종종 배열의 마지막 n 요소를 제외한 모든 것을 원한다는 것을 알게되었습니다. 다른 솔루션보다 더 읽기 쉬운 방식 으로이 기능을 수행했습니다.

class Array
  def all_but_the_last(n)
    self.first(self.size - n)
  end
end

이제 다음을 수행 할 수 있습니다.

arr = ["One", "Two", "Three", "Four", "Five"]
# => ["One", "Two", "Three", "Four", "Five"]

arr.all_but_the_last(1)
# => ["One", "Two", "Three", "Four"]

arr.all_but_the_last(3)
# => ["One", "Two"]

arr.all_but_the_last(5)
# => []

arr.all_but_the_last(6)
# ArgumentError: negative array size

호출자가이 메소드를 사용하는 방법을 책임 지도록 ArgumentError를 의도적으로 허용했습니다. 이 접근법에 대한 의견 / 비평을 듣고 싶습니다.


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.