mysqlのDBテーブルからSELECTしてきた上のデータを、下みたいにPHPで詰め直したいんだけど、どうやったらできるのか全然設計できなくて最近マジで鬱。助けてPHPer pic.twitter.com/IwwtOfeTVe
— HAL (@PET_HAL) 2019年2月6日
…とツイートを投稿したところ、
想定が間違っているかもですが、日付をtimestamp型にしてそれをindexにしてデータをを格納し、A,Bをindex単位でマージしたものを任意の期間で切り分ければ何とかなりそうな。
— まとっち (@raja_narinari) 2019年2月6日
…とのアドバイスをいただき、とりあえず想定通りの結果が得られるコードが書けました。
※Gistにも全く同じコードを公開しています。
try.php
<?php
function convert_date_into_timestamp($date) {
if (!$date) {
return null;
}
return strtotime($date);
}
$list = array();
$tmp = array(
'start_date' => '2019/01/21',
'end_date' => '2019/02/28',
'name' => 'A'
);
$list[] = $tmp;
$tmp = array(
'start_date' => '2019/02/22',
'end_date' => null,
'name' => 'B'
);
$list[] = $tmp;
$start_date_list = array();
$end_date_list = array();
$tmp = array();
$list_count = count($list);
for ($i = 0; $i < $list_count; $i++) {
$info = $list[$i];
$start_date = convert_date_into_timestamp($info['start_date']);
if ($start_date) {
$start_date_list[] = $start_date;
}
$end_date = convert_date_into_timestamp($info['end_date']);
if ($end_date) {
$end_date_list[] = $end_date;
}
$arr = array(
'start_date' => $start_date,
'end_date' => $end_date,
'name' => $info['name']
);
$tmp[] = $arr;
}
$start_date_list = array_unique($start_date_list);
$start_date_list = array_values($start_date_list);
sort($start_date_list);
$start_date_count = count($start_date_list);
for ($i = 0; $i < $start_date_count; $i++) {
if ($i === 0) {
continue;
}
$start_date_timestamp = $start_date_list[$i];
$end_date_list[] = strtotime('-1 day', $start_date_timestamp);
}
$end_date_list = array_unique($end_date_list);
$end_date_list = array_values($end_date_list);
sort($end_date_list);
$end_date_timestamp = array_key_last($end_date_list);
if ($end_date_timestamp) {
$start_date_list[] = strtotime('+1 day', $end_date_timestamp);
}
$start_date_list = array_unique($start_date_list);
$start_date_list = array_values($start_date_list);
sort($start_date_list);
$data = array();
$start_date_count = count($start_date_list);
for ($i = 0; $i < $start_date_count; $i++) {
$start_date_timestamp = $start_date_list[$i];
$end_date_timestamp = $end_date_list[$i];
$name = '';
for ($j = 0; $j < $list_count; $j++) {
$info = $tmp[$j];
$use_start_date_timestamp = $info['start_date'];
$use_end_date_timestamp = $info['end_date'];
if ($use_start_date_timestamp <= $start_date_timestamp
&& ($use_end_date_timestamp == null || ($end_date_timestamp != null && $use_end_date_timestamp >= $end_date_timestamp))) {
if (!empty($name)) {
$name .= '、';
}
$name .= $info['name'];
}
}
// 2019/04/24 追加(バグ対応:終了日 < 本日 の場合に空行が出力されてしまう)
if (empty($name)) {
continue;
}
$arr = array(
'start_date' => (string) date('Y-m-d', $start_date_timestamp),
'end_date' => $end_date_timestamp != null ? (string) date('Y-m-d', $end_date_timestamp) : '',
'name' => $name
);
$data[] = $arr;
}
var_dump(data);
期日が迫っていてブラッシュアップまで手が回せなかったのですが、改善の余地はまだまだありそうな気がしているので、時間がある時にリファクタリングしたいなあと思います。