web-dev-qa-db-ja.com

Ruby - 配列をテストする

正しい方法は何ですか。

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

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

それともその中のアイテムの数を取得する?

247
BuddyJoe

おそらくkind_of?()を使いたいでしょう。

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

配列に配列が必要であることを確認していますか?あなたはrespond_to?(method)を使うことができるかもしれません、それであなたのコードは必ずしも配列ではない類似したもののために働くでしょう。実際にarrayが必要な場合は、Array#kind\_of?メソッドを説明した投稿が最善です。

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

Array,をテストする代わりに、取得したものを1レベルのArray,に変換するだけなので、コードは1つのケースを処理するだけで済みます。

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

Rubyには、オブジェクトまたはオブジェクトの配列を取ることができるAPIを調和させるためのさまざまな方法があるので、何かがどうか知りたいのかどうかを推測しながらis Array、私は提案があります。

splat演算子にはたくさんのマジック が含まれています。 または必要に応じてArray(something)を呼び出すだけでArrayラッパーを追加できます。これは[*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であるときは、新しいオブジェクトを作成する必要がないからです。

54
DigitalRoss

[1,2,3].is_a? Arrayはtrueと評価されます。

16
dipole_moment

アイテムの概念を持ったものを追いかけているようですね。したがって、それがEnumerableかどうかを確認することをお勧めします。それは#countの存在も保証します。

例えば、

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

sizelengthおよびcountはすべて配列に対して機能しますが、ここではcountが正しい意味です(たとえば、'abc'.lengthおよび'abc'.sizeは機能しますが、'abc'.countはそのように機能しません)。

注意:文字列is_a?列挙可能なので、おそらくこれはあなたが望むものではありません...オブジェクトのような配列のあなたの概念に依存します。

12
Peter

試してください:

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

EDIT:他の答えは私のものよりはるかに優れています。

8
Lucas Jones

Array()の使用も検討してください。から Ruby Community Style Guide

明示的なArray checkや[* var]の代わりにArray()を使用してください。変数を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) }
5
GuyPaddock