2

キーがタイムスタンプで値がゼロのダミー配列を生成しています。開始は今日(時間部分のない日付)であり$days、過去の数日間に戻ります。

$days  = 10;
$limit = strtotime(date('Y-m-d'));
$start = $limit - (($days - 1) * 86400);

// Dummy array of timestamps and zeroes
$dummy = array_combine(range($start, $limit, 86400), array_fill(0, $days, 0));
var_dump($dummy);

array (size=10)
  1337551200 => int 0
  1337637600 => int 0
  1337724000 => int 0
  1337810400 => int 0
  1337896800 => int 0
  1337983200 => int 0
  1338069600 => int 0
  1338156000 => int 0
  1338242400 => int 0
  1338328800 => int 0 // Today is the last

この配列は、MySQL結果セットから抽出された別の配列とマージされます(その値はダミーの配列をオーバーライドする必要があります)。

$keys = array_map(function($e) { return strtotime($e['date']); }, $values);
$vals = array_map(function($e) { return intval($e['count']); },   $values);

// Array of real values coming from database
$reals = array_combine($keys, $vals);
var_dump($reals);

array (size=1)
  1338328800 => int 2 // Today

キーの並べ替えを操作するのでarray_merge(タイプのキーの場合integer)、配列演算子に切り替え+、結果の配列が並べ替えられます:新しいキーが最初に来ます:

var_dump($reals + $dummy);

array (size=10)
  1338328800 => int 2 // Today become the first
  1337551200 => int 0
  1337637600 => int 0
  1337724000 => int 0
  1337810400 => int 0
  1337896800 => int 0
  1337983200 => int 0
  1338069600 => int 0
  1338156000 => int 0
  1338242400 => int 0

したがって、問題は、+オペレーターがこれらのキーを最初に配置し、以下のように、ソート関数を使用せずにこれを解決するにはどうすればよいかということです。

$merged = $reals + $dummy;
ksort($merged);
var_dump($merged);

array (size=10)
  1337551200 => int 0
  1337637600 => int 0
  1337724000 => int 0
  1337810400 => int 0
  1337896800 => int 0
  1337983200 => int 0
  1338069600 => int 0
  1338156000 => int 0
  1338242400 => int 0
  1338328800 => int 2
4

2 に答える 2

1

回避策として、 の形式で文字列キーを使用して、インデックスの再作成YYYY-MM-DDを防ぐことができます。array_merge()また、タイムスタンプよりも説明的です。DatePeriodキーを簡単に作成するために使用できます。

最適なソリューションを探している場合は、次のようにします。

# begin timestamp
$ts = 1337551200;

# values from database
$values = [
  ['date' => '2012-05-23', 'count' => 42],
  ['date' => '2012-05-26', 'count' => 666]
];

# holds the key=>val pairs
$data = [];

foreach ($values as $value)
{
  $value_ts = strtotime($value['date']);

  # backfill all missing dates
  for ($missing_ts = $ts; $missing_ts < $value_ts; $missing_ts += 86400)
    $data[$missing_ts] = 0;

  # add date from database
  $data[$value_ts] = $value['count'];

  $ts = $value_ts + 86400;
}

# append all remaining dates
for ($now = time(); $ts <= $now; $ts += 86400)
  $data[$ts] = 0;

これは、データベースからのデータを 1 回反復するだけで、値が 0 の不足しているキーを挿入します。$values既にソートされている場合にのみ機能し、正確に 86400 秒離れている日によって異なります (元のソリューションと同様)。

「コピーして貼り付ける」準備ができていない可能性がありますが、最小限のオーバーヘッドでワンパス ソリューションを実装する方法についてのアイデアが得られるはずです。のような関数array_map()は非常に簡潔なコードを提供するのに適していますが、実際に大量のデータを扱っている場合は、このタイプのソリューションが断食になると思います。(調べるためのベンチマーク。)

于 2012-05-30T00:29:51.473 に答える
0

これは、+(配列に適用される)が、左側の配列に存在しない右側の配列からのデータを追加するためです。

これは、次のvar_dump($reals + $dummy);ことを意味します$reals。1つのアイテム(今日は最初で唯一の要素)で構成されるアイテムを取得し、そこからすべてを$dummy別のキーで追加します。

考えられる解決策は次のとおりです。

  1. データを並べ替える(あなたはそれを言った)
  2. 手動でマージしますforeach
于 2012-05-30T00:24:16.383 に答える