2

与えられた

a = nil # or [1,2]
b = [1,2] # or nil

中間体を割り当てたり、大量の定型コードを作成したりせずaに、連結を繰り返すことができますか?b

# meaning do this much more efficiently
((a || []) + (b || [])).each do |thing|
  # more lines here 
  puts thing
end

これはちょっと醜いです:

l = lambda{|thing| do_my_thing }
a.each{|thing| l.call(thing)} if a
b.each{|thing| l.call(thing)} if b
4

3 に答える 3

2

1.9 を使用している場合は、複数のスプラットの機能を使用します。

a = nil
b = [1, 2]
[*a, *b]
#=> [1, 2]

a = [3, 4]
b = nil
[*a, *b]
#=> [3, 4]

だから[*a, *b].each {}あなたが望むものとまったく同じようです。

于 2012-09-14T06:12:05.290 に答える
2

コンテナを作成したい場合 (含まれる要素が大きくても安価なはずです)、次のことができます。

[a,b].compact.each do |e|
  e.each do
    # stuff
  end
end

コンテナー配列を作成する必要がありますが、サブ配列の内容をコピーする必要がない (代わりに 2 つの配列ポインターを処理するだけである) ため、非常に高速で、GC で問題が発生することはありません。

別の解決策は、メソッドを作成することです。

def multi_each(*args,&block)
  args.each do |a|
    a.each(&block) if a
  end
end

multi_each(nil,[1],[2,3]) do |i|
  puts i 
end
# 1
# 2
# 3
于 2012-09-14T04:01:59.577 に答える
1

ラムダをブロック自体として渡すことで、持っているものをはるかに簡潔にし、醜いものを大幅に減らすことができます。

l = lambda { |thing| do_my_thing }
a.each(&l) if a
b.each(&l) if b
于 2012-09-14T04:25:49.430 に答える