2012-02-08 4 views
0

をインクリメントするワークアウト:私は各1日間隔で10個のタイムスタンプを持つ配列を作成したデータポイントPHP

$data_points = array(); 
$now = time(); 
$one_day = 60 * 60 * 24; 

for($i = 1; $i <= 10; ++$i) { 
    $key = $now - ($one_day * $i); 
    $data_points[$key] = 0; 
} 

print_r($data_points); 

Array 
(
    [1328642414] => 0 
    [1328556014] => 0 
    [1328469614] => 0 
    [1328383214] => 0 
    [1328296814] => 0 
    [1328210414] => 0 
    [1328124014] => 0 
    [1328037614] => 0 
    [1327951214] => 0 
    [1327864814] => 0 
) 

を今、私は過去10日間に様々な時間で開始したタスクの配列を持っています、私は自分の仕事がどの日になったのかを知りたい。

私は、各$data_pointをループに行くと、開始時刻が現在の日付よりも大きいと、次未満である場合には、その後、

これを行うには良い方法があることをデータ・ポイントをインクリメント見ましたか?

おかげ

+1

配列にタイムスタンプを使用する代わりに、 "yyyy-mm-dd"を使用して、タイムスタンプの代わりにDateTimesを使用し、DateTime-> format()を使用してそれぞれの日数を増やすことができます。 – thetaiko

+0

あなたの仕事の配列はどのように見えますか? – rdlowrey

+1

DateTimeを持っていない場合、 'date'を使ってタイムスタンプの" Y-m-d "形式の表現を得ることができます。 http://www.php.net/manual/en/function.date.php – thetaiko

答えて

1

さて、あなたは単純な配列ではなく、バイナリ検索ツリーにデータを置くことができ、検索時間を短縮します。

問題があるかどうかは、データセットの大きさによって異なります。もちろん、新しい日付を追加するたびにツリーのバランスをとる必要があります。

0

あなたは**間隔はあなたが期待する数である

$now = date('Ymd'); 
$task = date('Ymd',$tasktime); 
$interval = $task - $now; 

**コメントに尋ねとしてのDateTimeの使用を避けるために、更新DateTime class

$now = new DateTime(); 
$task = new DateTime('2012-02-20'); 
$interval = $taks->diff($now); 
echo 'Here is the position you need:' . $interval->format('%R%a days'); 

を使用することができます。

+0

残念ながら、DateTimeクラスは自分の環境で使用できません – Lizard

0

私は良い方法があると思います。

あなたは配列内のタイムスタンプを開始するタスクを持っていると仮定すると、アルゴリズムは次のようになります:あなたは一つだけアレイ上のループます。このように

for each task starting timestamp 
    timestamp <- $now - timestamp // you will obtain task age in seconds 
    timestamp <- timestamp/(60*60*24) // you will obtain task age in days 
    // round resulting timestamp with a precision of 0 if you want to obtain the task age in integer days. 
end for each 

。これはあなたの方法よりも安いでしょう。

あなたのタスクがSQLデータベースのものである場合、明らかにSQLの方が優れています。

0

私はこの質問が古いことを知っていますが、受け入れられた回答がないので、答えは楽しい質問のようです - ここに行きます!

質問に基づいて、アルゴリズムはBig OO(10n)です。ここで、nはタスクの数です。つまり、多くのものに比べてかなり効率的です。指摘したように、バイナリ検索ツリーはO(log(n))の方が速くなりますが、実装すると処理中に節約に値するものではありません。けれども、あなたはそれが少しより効率的にするなど、何か使用して結果O(n)を持つことができます。デフに

$now = time(); 
$oneDay = 86400; //60 * 60 * 24 
foreach($tasks as $task) { 
    //assuming now that $task is the timestamp of the task 
    //extra paranthesis added for easier reading 
    $dif = $now - ($oneDay * ceil(($now - $task)/$oneDay)); 
    $data_points[$dif]++; 
} 

数学を以下のようです。 $now-$taskは、秒単位の2つのタイムスタンプの差です。これは、タスクが発生した過去の日数を取得するために、$oneDayで除算します。今度は$nowが新しい日の始まりで、12時間前に起こったイベントが「昨日」だった場合は、ceilを使用して次の整数に丸めます。 '.5'は '1'にな​​ります。そこから、$oneDayを掛けて、前に作成した$data_points配列で動作するようになった日の秒数を取得します。その結果を取り出して$nowから引き取り、再度$data_points配列で処理します。その結果、作成した配列内のタイムスタンプと一致するタイムスタンプが得られ、そのタイムスタンプをキーとして使用し、それに応じて増分します。

これにより、$data_pointsアレイ全体をループごとにループせずに、複雑さをO(10n)からO(n)に減らすことができなくなります。

とにかく、私の答えは、あなたの数式がなぜ非効率的ではないのかを説明するのに役立ちますが、それほど効率が良くない方法を示してくれることを願っています。

関連する問題