0

したがって、次のようなタイムスタンプの配列がある場合 (実際にはこれよりも多く):

2013-07-27 18:02:59.865572
2013-07-27 18:29:00.132601
2013-07-27 19:00:00.081585
2013-07-27 19:29:00.273857
2013-07-27 20:00:00.011761

Ruby で最もエレガントな方法は何でしょう?

これを行うには醜いループと if ステートメントの束を思い描くことができますが、初心者の Ruby プログラマーとして、これを行うためのはるかに洗練された方法があると思います (絶対に見つけられません!)。

ありがとう!

4

2 に答える 2

1

それはいくつかのことに依存します。

  • 探しているタイムスタンプが配列内にあることがわかっているかどうか。
  • 間の何を意味します。
  • 配列内の要素が一意かどうか。

配列がソートされているか、事前に自分でソートすると仮定しましょう。

が配列内にあることがわかっている場合your_timestampは、 でそのインデックスを見つけることができますtimestamp_array.index(your_timestamp)。論理的には、 your_timestamp が間にある要素には、すぐ上とすぐ下にインデックスがあります。注意すべき点が 2 つあります。

  1. 配列のいずれかの端から落ちる。
  2. タイムスタンプが重複しています。

your_timestampが配列の最初または最後の要素の場合、最初の要素のすぐ下または最後の要素のすぐ上のインデックスを持つ要素はありません。

配列に重複したタイムスタンプが含まれている場合、値の 1 つとして返さyour_timestampれる可能性があります。あなたはそれをしたくないようですが、厳密には正しいか間違っているかという答えはありません。アプリケーションに依存します。

your_timestampが配列内にあるかどうかわからない場合、または値の 1 つとして使用したくないyour_timestamp場合 (並べ替えられた配列の最初または最後の要素でない限り)、これはより良いアプローチかもしれません。

timestamp_array.sort.each_cons(2){ |ts| 
  # If your desired timestamp is in the timestamp array, you'll
  # get at least two pairs of timestamps.
  answer.concat ts if your_desired_timestamp.between?(ts[0], ts[1])
}
# If you have more than 2 elements, return only the first and last element.
if answer.length > 2
  answer = answer.first, answer.last
end
p answer

["2013-07-27 18:29:00.132601", "2013-07-27 19:29:00.273857"]

これは、重複したタイムスタンプに対して正しく機能し、配列のどちらかの端から落ちる危険はありません。

いくつかの最適化が利用可能です。たとえば、二分探索 (bsearch メソッド) に切り替えることができます。これは、配列が非常に大きい場合に有効です。条件を削除できますif answer.length > 2; 等

于 2013-07-28T19:10:21.227 に答える