将二维数组合并成组

问题描述 投票:0回答:3

我正在重构一个日历应用程序。该日历具有用户定义的网格(可以进行预订的时段),但也需要显示“离网”预订。想想 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;
(请忽略可能的关键字,由于格式原因不引用,也没有测试查询)。

php arrays multidimensional-array
3个回答
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
循环。


0
投票

“我查了PHP手册,但内置数组函数没有 完全按照我的需要去做。”

内置数组功能比仅仅循环遍历一堆数组更有效,您应该看看 php 中的 array_mergearray_merge_recursive 以获得如何执行此操作的更有效答案,或者按照信息进行操作使用 SQL 从数据库中拉取。

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

    $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']];
            }
        }
    }

0
投票
  1. 将临时的一级键分配给
    $officialGrid
    ,这将作为结果数组的基础数据。
  2. 迭代
    $bookings
    数组。
  3. 当第一次遇到某一行的时间时,直接将其压入结果数组中。
  4. 如果之前遇到过一行的时间,请使用条件逗号和空格扩展结果数组中的
    $content
    列值,然后是新行的
    content
    值。
  5. 循环结束后,按临时键(时间值)排序。
  6. 通过调用
    array_values()
    重新索引结果(删除临时键)。

代码:(演示

$result = array_column($officialGrid, null, 'time');
foreach ($bookings as $row) {
    if (!isset($result[$row['time']])) {
        $result[$row['time']] = $row;
    } else {
        $result[$row['time']]['content'] = sprintf(
            '%s%s',
            (isset($result[$row['time']]['content']) ? "{$result[$row['time']]['content']}, " : ''),
            $row['content']
        );
    }
}
ksort($result);
var_export(array_values($result));
© www.soinside.com 2019 - 2024. All rights reserved.