[ruby] 루비-배열 테스트

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

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

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

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



답변

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

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


답변

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

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


답변

테스트하는 대신 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사용하는 경우 새 객체를 만들 필요가 없기 때문에 사용 하는 것이 더 빠릅니다 .


답변

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


답변

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

예를 들어

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

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

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


답변

시험:

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

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


답변

또한 사용을 고려하십시오 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) }