루비-배열 테스트


265

올바른 방법은 무엇입니까?

is_array("something") # => false         (or 1)

is_array(["something", "else"]) # => true  (or > 1)

또는 항목의 개수를 구하려면?


7
실제 배열을 원하십니까? 아니면 배열과 비슷한 것을 원하십니까?
Kathy Van Stone

1
Ruby에는 형식 안전성이 없습니다. 변수가 배열인지 여부에 대해 걱정하지 마십시오. 이 메소드는 그것이 있다고 가정하고 계속해서 카운트합니다. my_array.count
user132447

더 관용적 인 Ruby에 대해서는 zgchurch 및 DigitalRoss의 답변을 읽으십시오.
DanT

답변:


516

을 사용하고 싶을 것입니다 kind_of().

>> s = "something"
=> "something"
>> s.kind_of?(Array)
=> false
>> s = ["something", "else"]
=> ["something", "else"]
>> s.kind_of?(Array)
=> true

31
이이기도 is_a?하고 instance_of?. 참조 stackoverflow.com/questions/3893278/...
나단 긴

2
유형 검사는 Java 용입니다. 계속해서 변수에 카운트를 호출하십시오. 방법이 예상대로 작동하는지 확인하기 위해 단위 테스트를 작성하십시오.
user132447

14
@ user132447 실제로 java는 타입이 안전하므로 어떤 타입을 검사하는 것에 대해 걱정할 필요가 없습니다
grinch

8
루비와 같은 언어에서는 이것이 좋은 습관이라고 생각하지 않기 때문에 이것을 하향 투표했습니다. @zgchurch의 대답은 분명히 질문에 대한 훨씬 관용적 인 접근 방식입니다. 이런 경우에 나는 맹목적으로 샷건을주지 않고 OP가 무엇을 의미하는지 알아 내려고 시도하는 것이 훨씬 더 합리적이라고 생각한다.
Per Lundberg

1
kind_of?()다른 솔루션보다 사용하고 싶 습니까? 다른 사람에 대한 귀하의 답변의 이점에 대한 일부 설명은 향후 독자에게 도움이 될 것입니다.
AlbertEngelB

148

당신은 확신 이 필요 배열로? respond_to?(method)코드가 반드시 배열이 아닌 유사한 것들 (다른 몇 가지 중요한 것들)에서 작동하도록 코드 를 사용할 수 있습니다 . 실제로가 필요 array하면 Array#kind\_of?방법을 설명하는 게시물 이 가장 좋습니다.

['hello'].respond_to?('each')

1
이 경우 배열이 될 것이라고 확신합니다. 그러나이 방법도 알고 싶습니다. +1
BuddyJoe

흥미로운 아이디어는 데이터 구조에 푸시 / 팝을 사용하고 있습니다. 배열 이외의 다른 방법으로 해당 메소드에 응답합니까?
Drew

3
더 배열 같은 것을 원한다면 원할 수 있습니다 respond_to?(:to_ary).
Andrew Grimm

21
일반적으로 이것은 OO 개발에 좋은 습관입니다. 누군가가 기본적으로 말한 곳을 읽었습니다. 객체에서 메소드를 호출한다고 상상하지 마십시오. 당신은 그들에게 메시지를 보내고 있습니다. 객체가 메시지에 응답하는 방법을 알고있는 경우, 해당 클래스가 무엇인지, 이름이 지정된 메소드가 있는지 또는 method_missing을 통해 동적으로 응답을 작성하는지는 상관하지 않습니다. 중요한 것은 메시지에 응답 할 수 있습니까? 이를 통해 기능과 구현을 더 잘 추상화 할 수 있습니다. 여전히 올바르게 응답하는 한 나중에 사용하는 객체를 변경할 수 있습니다.
Nathan Long

2
이것의 유일한 문제는 색인 된 반복 가능 항목인지 확인하고 싶습니다. 따라서 배열, 링크 된 목록 등이 멋지지만 해시와 같은 키 값 저장소는 원하지 않습니까?
Colton Voege 2012 년

58

테스트하는 대신 Array,하나의 레벨로 얻은 것을 변환 Array,하여 코드가 하나의 사례 만 처리하면됩니다.

t = [*something]     # or...
t = Array(something) # or...
def f *x
    ...
end

루비에는 객체 또는 객체 배열을 취할 수있는 API를 조화시키는 다양한 방법이 있으므로 무언가 배열 인지 알고 싶은 이유를 추측 하면 제안이 있습니다.

플랫 연산자는 마법 많이 포함 당신이 볼 수, 또는 당신은 단지 호출 할 수 있습니다 Array(something)필요한 경우 배열 래퍼를 추가 할 것이다. 이 [*something]경우 와 비슷합니다 .

def f x
  p Array(x).inspect
  p [*x].inspect
end
f 1         # => "[1]"
f [1]       # => "[1]"
f [1,2]     # => "[1, 2]"

또는 매개 변수 선언에서 splat 을 사용한 다음 .flatten다른 종류의 수집기를 제공 할 수 있습니다. (그 문제 .flatten에 대해서도 위의 전화를 걸 수 있습니다.)

def f *x
  p x.flatten.inspect
end         # => nil
f 1         # => "[1]"
f 1,2       # => "[1, 2]"
f [1]       # => "[1]"
f [1,2]     # => "[1, 2]"
f [1,2],3,4 # => "[1, 2, 3, 4]"

그리고 gregschlom 덕분에 Array(x)이미 Array사용하는 경우 새 객체를 만들 필요가 없기 때문에 사용 하는 것이 더 빠릅니다 .


그래서 단일 항목이라면 단일 항목이 포함 된 배열이됩니까?
BuddyJoe

예. 이미 배열 인 경우 두 번째 배열 래퍼를 추가하지 않고 유지합니다.
DigitalRoss

2
잊지 마세요 : [*nil] => []. 따라서 빈 배열로 끝날 수 있습니다.
Christopher Oezbek

3
Array(foo)보다 효율적으로 사용[*foo]
gregschlom

23

[1,2,3].is_a? Array true로 평가됩니다.


1
이것은 거의 7 년 동안이 사이트에 있었던 해답에 무엇을 추가합니까?
Martin Tournoij

6
@ Carpetsmoker is_a?이 전체 스레드에서 참조하는 간결한 답변이 없습니다 . 가장 가까운 것은입니다 [1,2,3].is_a? Enumerable. 나는 아직도이 대답을하는 것이 가치가 있다고 생각합니다.
dipole_moment

4
당신은 알고있다. .. 당신은 실제로 옳다. 나는 맹세 할 수 있었다.
Martin Tournoij

16

항목 개념이있는 무언가를 따르는 것처럼 들립니다. 따라서 그것이 있는지 확인하는 것이 좋습니다 Enumerable. 또한의 존재를 보장합니다 #count.

예를 들어

[1,2,3].is_a? Enumerable
[1,2,3].count

반면, 점에 유의 size, lengthcount배열에 대한 모든 작업, count(예를 들어, - 여기에서 우측 의미입니다 'abc'.length'abc'.size두 작품은,하지만 'abc'.count그런 일을하지 않습니다).

주의 : 문자열 is_a? 열거 가능하므로 아마도 이것이 원하는 것이 아닙니다 ... 객체와 같은 배열의 개념에 달려 있습니다.


11

시험:

def is_array(a)
    a.class == Array
end

편집 : 다른 대답은 내 것보다 훨씬 낫습니다.


6

또한 사용을 고려하십시오 Array(). 로부터 루비 커뮤니티 스타일 가이드 :

Array로 취급하려는 변수를 처리 할 때 명시 적 Array check 또는 [* var] 대신 Array ()를 사용하지만 이것이 확실하지는 않습니다.

# bad
paths = [paths] unless paths.is_a? Array
paths.each { |path| do_something(path) }

# bad (always creates a new Array instance)
[*paths].each { |path| do_something(path) }

# good (and a bit more readable)
Array(paths).each { |path| do_something(path) }

때문에 해시를 통과 할 때 예기치 않은 결과를 얻을 수 to_a새로운 배열에 추가 각 인수에라고, 그래서 Array({id: 100})반환[[:id, 100]]
브렌트
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.