2339


Array同士を足し合わせるときに、`+`
が使えるかと思うのですが、しかし、片方が`nil`だった場合に、`+`を行おうとすると、エラーが起きてしまいます。また似たようなメソッドであるところの`concat`も同じように`nil`が入ってくるとエラーが入ってくるかと思わます。

そこで、ある変数が二つあるとして、この片方が`nil`である可能性がある場合に、これらを安全に合わせたいと思っています。書き方としては、以下のような書き方があることはわかっています。

以下の事例では`a`は必ずArrayがセットされており、`b`には`nil`が入っている可能性がある場合とします:

[code]

    a = [1, 2, 3]
    b = nil # わかりやすくnilをセット
    
    c = a + b.to_a
    p c
    # output: [1, 2, 3]
    
    c = b.nil? ? a : a + b
    p c
    # output: [1, 2, 3]
    
    c = a.concat b || []
    p c
    # output: [1, 2, 3]
    
[/code]

とはいえ、もっとダイレクトに`nil`の可能性があってもArray同士を足し合わせることができる方法がありそうな気がしたのですが、もしそのような方法があれば教えて下さい


CC BY-SA 3.0
2014-12-21T18:10:22.493
2336
2014-12-22T08:21:19.983
2014-12-21T18:40:05.957
939
939
question
ruby
Arrayが期待される変数同士を足し合わせるとき、片方がnilの可能性がある場合の書き方


長めだけど、 map/reduce 感があるのでわかりやすいかも。

[code]

    a = [1, 2, 3]
    b = nil
    c = [3, 4, 5]
    d = [nil]; 
    
    [a, b, c, d].compact.reduce(:+) # 重複あり
    # => [1, 2, 3, 3, 4, 5, nil]
    
    [a, b, c, d].compact.reduce(:|) # 重複なし
    # => [1, 2, 3, 4, 5, nil]
    
[/code]


CC BY-SA 3.0
2014-12-21T21:02:05.423
2339
2014-12-21T21:02:05.423
4978
2336
answer


stackoverflow に次の QA がありました。

  * Merge arrays if not nil and not empty   
<https://stackoverflow.com/questions/12228709/merge-arrays-if-not-nil-and-not-
empty>

そこには２つの方法が示されていました。

[code]

    a = [1,2,3]
    b =nil
    
    # 回答 1
    p [a, b].compact.reduce([], :|)  # => [1, 2, 3]
    p [b, a].compact.reduce([], :|)  # => [1, 2, 3]
    
    # 回答 2
    p Array(a) | Array(b)  # => [1, 2, 3]
    p Array(b) | Array(a)  # => [1, 2, 3]
    
[/code]


CC BY-SA 3.0
2014-12-21T21:42:55.203
2341
2014-12-21T21:42:55.203
2017-05-23T12:38:56.467
-1
2987
2336
answer


`a + b.to_a` ではいかがでしょうか。 `nil.to_a` は `[]` を返し、配列の `to_a` は自分自身を返します。


CC BY-SA 3.0
2014-12-22T05:34:52.313
2367
2014-12-22T05:34:52.313
5492
2336
answer


配列が入れ子になっていないと仮定できるなら `Array#flatten` と `Array#compact` を続けて使うのがスッキリしてよさそうです。

[code]

    irb(main):001:0> a = [1, 2]
    => [1, 2]
    irb(main):002:0> b = nil
    => nil
    irb(main):003:0> a + b
    TypeError: no implicit conversion of nil into Array
        from (irb):3:in `+'
        from (irb):3
        from /Users/mitsuhiro.takano/local/var/rbenv/versions/2.1.0/bin/irb:11:in `<main>'
    irb(main):004:0> c = a | b
    TypeError: no implicit conversion of nil into Array
        from (irb):4:in `|'
        from (irb):4
        from /Users/mitsuhiro.takano/local/var/rbenv/versions/2.1.0/bin/irb:11:in `<main>'
    irb(main):005:0> [a, b]
    => [[1, 2], nil]
    irb(main):006:0> [a, b].flatten
    => [1, 2, nil]
    irb(main):007:0> [a, b].flatten.compact
    => [1, 2]
    
[/code]


CC BY-SA 3.0
2014-12-22T08:21:19.983
2374
2014-12-22T08:21:19.983
982
2336
answer