将二维数组合并为组

时间:2014-10-06 23:40:26

标签: php arrays multidimensional-array

我正在重构日历应用。日历具有用户定义的网格(可以进行预订的插槽),但需要显示"非网格"预订也是如此。想想"常规"在08:00,09:00和"不规则"有人在08:39预订的时段。出于商业原因,我需要以不同方式显示这些插槽(CSS),否则它们的行为相同。我已经搜索了PHP手册,但是内置的数组功能并不能完全满足我的需要。

$officialGrid = array(
    array('grid' => TRUE, 'time' => '08:00', 'content' => NULL),
    array('grid' => TRUE, 'time' => '09:00', 'content' => NULL));

$bookings = array(
    array('grid' => NULL, 'time' => '08:00', 'content' => 'Paul Simon'),
    array('grid' => NULL, 'time' => '08:00', 'content' => 'Art Garfunkel'),
    array('grid' => NULL, 'time' => '08:39', 'content' => 'Homer J. Simpson'));

我可以添加这些数组,但出于性能原因,请将结果缩短为:

$timeSlotsToDisplay = array(
    array('grid' => TRUE, 'time' => '08:00', 'content' => 'Paul Simon, Art Garfunkel'), //regular
    array('grid' => NULL, 'time' => '08:39', 'content' => 'Homer J. Simpson'), //irregular
    array('grid' => TRUE, 'time' => '09:00', 'content' => NULL)); //vacant

我也可以灵活地更改值的数据类型(content可能是一个数组)。除了开始循环和比较之外,还有合并这些数组的优雅解决方案吗?

PS:只是为了说明,在PostgreSQL术语中,我需要SELECT DISTINCT ON (time) grid, time, string_agg(content) FROM myDB GROUP BY time ORDER BY time, grid;(请忽略可能的关键字,而不是因为格式化而引用,也没有测试查询)。

2 个答案:

答案 0 :(得分:2)

我认为循环没有问题..但我建议$officialGrid数组的另一个结构

$officialGrid = array(
    '08:00' => array('grid' => TRUE, 'content' => NULL),
    '09:00' => array('grid' => TRUE, 'content' => NULL));

$bookings = array(
    array('grid' => NULL, 'time' => '08:00', 'content' => 'Paul Simon'),
    array('grid' => NULL, 'time' => '08:00', 'content' => 'Art Garfunkel'),
    array('grid' => NULL, 'time' => '08:39', 'content' => 'Homer J. Simpson'));

$timeSlotsToDisplay = $officialGrid;

array_map(function($el) use(&$timeSlotsToDisplay, $officialGrid) {
   $timeSlotsToDisplay[$el['time']] = array(
     'content' => 
       (isset($timeSlotsToDisplay[$el['time']]) ?
        trim($timeSlotsToDisplay[$el['time']]['content'], ',') . ',' : '') .
       $el['content'],
     'grid' => isset($officialGrid[$el['time']]) ? true : null
   );
}, $bookings);

ksort($timeSlotsToDisplay);
var_dump($timeSlotsToDisplay);

array_map可以替换为单个foreach循环。

答案 1 :(得分:0)

  

“我已经搜索了PHP手册,但内置的数组函数却没有   完全按照我的需要做。“

内置数组功能比循环遍历一堆数组更有效,你应该看一下php中的array_mergearray_merge_recursive,以便更有效地回答如何执行此操作,或者在使用SQL从数据库中下载信息时执行此操作。

对于一个实用的php解决方案,如果你可以循环遍历每个2d数组中的每一行并获取你想要的信息,但是这假设$ officialGrid中每个数组的键的结构与每个数组的键相同。 $预订。它应根据“时间”循环和匹配数据,并跳过预订中不匹配的数据。根据您拥有循环的信息行数可以很好地与数组一起使用,但它们远非最佳。

    $officialGrid = Array(
        Array('grid' => TRUE, 'time' => '08:00'  // ... arrays assumed to be populated with example data above

    $bookings = Array(
        Array('grid' => NULL, 'time' => '08:00'  // ... arrays assumed to be populated with example data above

    // fill final array with content from $bookings
    $timeSlotsToDisplay = $bookings;


    foreach($officialGrid as $officalkey=>$officalobj) {
        foreach($timeSlotsToDisplay as $bookkey=>$obj) {
            if(!isset($officialGrid[$officalobj['time']]) || !isset($timeSlotsToDisplay[$bookobj['time']])) {
               //one of them is not set.. error
            }

                //if the times match when looping
            if( $officialGrid[$officalobj['time']] == $timeSlotsToDisplay[$bookobj['time']]) {
                //keeps the information from officialgrid  data for column, and keep $booking data for content column
            //the null grid entries will just stay the same, as $bookings oringally had
                $timeSlotsToDisplay[$officalobj['grid']];
                $timeSlotsToDisplay[$bookobj['time']] 
                $timeSlotsToDisplay[$bookobj['content']];
            }
        }
    }