57
(1..4).collect do |x|
  next if x == 3
  x + 1
end # => [2, 3, nil, 5]
    # desired => [2, 3, 5]

条件nextが満たされた場合、配列にcollect入れますが、条件が満たされた場合、返された配列に要素をnil入れないようにしています。delete_if { |x| x == nil }返された配列を呼び出さずにこれは可能ですか?

(Ruby 1.8.7 を使用。私のコードの抜粋はかなり抽象化されています)

4

6 に答える 6

78

Enumerable#rejectまさに目的を果たす方法があります:

(1..4).reject{|x| x == 3}.collect{|x| x + 1}

あるメソッドの出力を別のメソッドの入力として直接使用することは、メソッド チェーンと呼ばれ、Ruby では非常に一般的です。

ところで、map(またはcollect)は、列挙可能な入力を出力に直接マッピングするために使用されます。異なる数の要素を出力する必要がある場合は、別のメソッドが必要になる可能性がありますEnumerable

inject編集: いくつかの要素が 2 回繰り返されるという事実に悩まされている場合は、 (または名前が付けられた同様の方法each_with_object)に基づいて、あまり洗練されていないソリューションを使用できます。

(1..4).each_with_object([]){|x,a| a << x + 1 unless x == 3}
于 2011-03-01T09:11:45.470 に答える
49

結果の配列を呼び出すだけ.compactで、配列内の nil のインスタンスがすべて削除されます。既存の配列を変更したい場合 (変更しない理由はありません)、次を使用します.compact!

(1..4).collect do |x|
  next if x == 3
  x
end.compact!
于 2011-03-01T08:42:46.173 に答える
4

単なる提案です。次のようにしてみませんか。

result = []
(1..4).each do |x|
  next if x == 3
  result << x
end
result # => [1, 2, 4]

そのようにして、別の反復を保存して、配列から nil 要素を削除しました。それが役立つことを願っています=)

于 2011-03-01T08:58:35.307 に答える
0

意思決定をヘルパー メソッドに取り込み、次の方法で使用できますEnumerable#reduce

def potentially_keep(list, i)
  if i === 3
    list
  else
    list.push i
  end
end
# => :potentially_keep

(1..4).reduce([]) { |memo, i| potentially_keep(memo, i) }
# => [1, 2, 4]
于 2014-06-15T05:52:15.213 に答える
0

私は使用することをお勧めします:

(1..4).to_a.delete_if {|x| x == 3}

collect + next ステートメントの代わりに。

于 2011-03-01T08:48:00.227 に答える