2012-01-09 4 views
3

1から4000までの異なるIDを持つ配列があります。その配列に入るIDを持つデータベースにいくつかの要素を追加する必要があります。可能な限り最大のIDは4000です(私の場合はそうではありません)ので、私は新しい要素に使用できる最小の未使用IDを見つけることができるようにしたいと思います。Ruby:ID配列の最低自由IDを見つける

私はC++でそれを行う方法を知っていましたが、私はRubyでかなり新しいので、助けを求めています。 C++では、array [i] == array [i + 1] - 1であるかどうかを調べるループを作成します。そうでない場合、新しいIDはarray [i] + 1になります。

私はRubyでそれをどのように書くのか考えていません。

ありがとうございました。

+0

これは、月に月に、多分バナナにリンゴを参照番号1をもたらします。通常の手順では、データベースにIDの列を管理させます。あなたが4000の最大値を持っているという事実は、IDが意味を持つように見えます(0-4000はカテゴリーフード、4001-5000はおもちゃです) - 悪い考えです。 – steenslag

答えて

5
array = [1, 2, 3, 5, 6] 
(1..4000).to_a.-(array).min 
+0

+1 @澤、とても素敵で簡潔です。非常に迅速に実行する必要があります。 –

+0

@theTinManありがとう、Tin Man。 – sawa

+0

これは確かに非常に、非常に賢いです – maprihoda

3
def first_unused_id(ids) 
    index = ids.each_index.find{|i| ids[i] + 1 != ids[i+1] } 
    ids[index] + 1 
end 

いくつかの説明:

  • each_indexは、配列のインデックスを与えるEnumeratorに配列を変換します。
  • findは、渡されたブロックからtrueを返す最初の要素を返します。
6

範囲を使用して、あなたの配列の一部ではない最初の要素を見つけることができます:

array = [1,2,3,5,6] 
(1..4000).find { |i| !array.include?(i) } 
# => 4 
+1

これは非常に非効率的なのでしょうか?メソッドは何千回も呼び出すことができます(二次的な複雑さです)。 – maprihoda

+0

ええ、間違いなく、最初の利用可能なIDが高いほど遅くなります( '3999、顕著な遅延があります)。他の答えはこれに対処する。 –

0

方法については、この1:

ディランの答えにこれが似
(1..4000).find { |i| array[i-1] != i } 

配列の[n-1]番目のメンバーがnであるかどうかをチェックするだけです。そうでない場合、そのインデックスは「オープン」であり、返されます。このソリューションは、唯一その配列を見つけるだろう

array = [1,2,3,5,6] 

このため

ので、インデックスではなく、4000ごとに1つのチェックを...必要です[4-1]!= 4(なぜなら配列[3] = 5)と最初の利用可能なIDとして4を返します。

(これはインデックスのソートされた配列を必要とするが、それは、これまで想定されている)

+1

これは、 'array [0]'が1つではなく0になります。 'array [i-1]'でなければなりません。また、 '!array [i]'は常に 'false'なので、投稿したコードはそのままでは動作しません。 'array [i-1]!= i' –

+0

ディランに感謝!編集されました。 – elijah

0
array = [1, 2, 3, 5, 6] 

def lowest_unused(ids) 
    ids.find { |e| ids.index(e) + 1 != e } - 1 
end 

p lowest_unused(array) # 4 
+0

Jakub Hamplの答えに似ていますが、少しシンプルです – maprihoda