1

ランダム出力(文字列)を生成する関数があります。

3つの異なる出力(文字列)が得られるまで、その関数を呼び出す必要があります。

関数を呼び出すことによって3つの一意の文字列を含む配列を生成する最も洗練された方法は何ですか?指定された試行回数で出力が生成されない場合に関数を呼び出すことができる回数に制限がありますか?

これが私が現在持っているものです:

output = []
limit_calls = 5
limit_calls.times do |i|
  str = generate_output_function
  output.push str
  break if output.uniq.size > 2
end

これを美化/1行に短縮することはできますか?私はルビーでかなり確信しています..:)

ありがとう

4

2 に答える 2

3

セットを使用すると、(少し)簡単になります。

require 'set'
output = Set.new
limit_calls = 5
call_count = 0
while output.size < 3 and call_count < limit_calls
  output << generate_output_function 
  call_count += 1
end
output

または配列を使用

output = []
limit_calls = 5
while output.size < limit_calls and output.uniq.size < 3
  output << generate_output_function 
end
output.uniq

通話制限付きで更新します。アレイバージョンが勝ったようです!ありがとうイアン!

また、注入を使用してバージョンを熟考します。

更新2-注入あり:

5.times.inject([]) { |a, el| a.uniq.size < 3 ? a << generate_output_function : a }

あなたのワンライナーがあります。従うのが少し難しいので、私がそれを好むかどうかはわかりません.....

于 2012-07-24T08:43:46.293 に答える
1

Froderikの回答は、call_limit要件を見逃していました。次のような関数はどうですか...

def unique_string_array(call_limit)
  output = []
  calls = 0
  until (output.size == 3 || calls == call_limit) do
    (output << generate_output_function).uniq! && calls+=1
  end
  output
end

ワンライナーではありませんが、読み取り可能です...この実装では、サイズ3未満の配列になる可能性があります。最も重要なことは、必要な動作を表明するテストがあることです。(これを徹底的にテストするには、generate_output_functionの呼び出しをスタブアウトする必要があります)

于 2012-07-24T09:00:17.990 に答える