136

配列、単一要素、または nil を指定すると、配列が取得されます。後者の 2 つは、それぞれ単一要素配列と空の配列です。

私は、Ruby が次のように動作すると誤って考えました。

[1,2,3].to_a  #= [1,2,3]     # Already an array, so no change
1.to_a        #= [1]         # Creates an array and adds element
nil.to_a      #= []          # Creates empty array

しかし、実際に得られるものは次のとおりです。

[1,2,3].to_a  #= [1,2,3]         # Hooray
1.to_a        #= NoMethodError   # Do not want
nil.to_a      #= []              # Hooray

したがって、これを解決するには、別のメソッドを使用するか、使用する予定のすべてのクラスの to_a メソッドを変更してメタ プログラムを作成する必要があります。これは私にとっては選択肢ではありません。

したがって、メソッドは次のとおりです。

result = nums.class == "Array".constantize ? nums : (nums.class == "NilClass".constantize ? [] : ([]<<nums))

問題は、それが少し混乱していることです。これを行うエレガントな方法はありますか?(これがこの問題を解決するための Ruby っぽい方法である場合、私は驚くでしょう)


これにはどのようなアプリケーションがありますか? なぜ配列に変換するのでしょうか?

Rails の ActiveRecord では、say を呼び出すと、user.posts投稿の配列、単一の投稿、または nil のいずれかが返されます。この結果に作用するメソッドを作成する場合、メソッドが配列を受け取ると仮定するのが最も簡単です。配列には、0 個、1 個、または多数の要素が含まれる可能性があります。方法の例:

current_user.posts.inject(true) {|result, element| result and (element.some_boolean_condition)}
4

10 に答える 10

136

ActiveSupport (Rails) の場合:Array.wrap

Array.wrap([1, 2, 3])     # => [1, 2, 3]
Array.wrap(1)             # => [1]
Array.wrap(nil)           # => []
Array.wrap({a: 1, b: 2})  # => [{:a=>1, :b=>2}]

Rails を使用していない場合は、rails sourceと同様に独自のメソッドを定義できます。

class Array
  def self.wrap(object)
    if object.nil?
      []
    elsif object.respond_to?(:to_ary)
      object.to_ary || [object]
    else
      [object]
    end
  end
end
于 2014-03-16T04:59:06.333 に答える
21

最も簡単な解決策は、 を使用すること[foo].flatten(1)です。他の提案されたソリューションとは異なり、(ネストされた) 配列、ハッシュ、およびnil:

def wrap(foo)
  [foo].flatten(1)
end

wrap([1,2,3])         #= [1,2,3]
wrap([[1,2],[3,4]])   #= [[1,2],[3,4]]
wrap(1)               #= [1]
wrap(nil)             #= [nil]
wrap({key: 'value'})  #= [{key: 'value'}]
于 2015-04-03T11:38:14.637 に答える
20

Array(whatever)トリックを行う必要があります

Array([1,2,3]) # [1,2,3]
Array(nil) # []
Array(1337)   # [1337]
于 2013-08-21T13:28:21.740 に答える
7

どうですか

[].push(anything).flatten
于 2014-11-09T19:12:33.123 に答える
2

明白なことを述べるリスクがあり、これが地球とその周辺地域でこれまでに見られた最もおいしい構文糖衣ではないことを知っているため、このコードはあなたが説明したことを正確に行うようです:

foo = foo.is_a?(Array) ? foo : foo.nil? ? [] : [foo]
于 2015-08-11T13:54:36.257 に答える