首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >按一列合并多维数组数据,并确保所有行都包含所有列

按一列合并多维数组数据,并确保所有行都包含所有列
EN

Stack Overflow用户
提问于 2011-01-20 14:27:40
回答 2查看 1.7K关注 0票数 0

我有一个数组,它包含来自两个或多个数据库查询的数据。

合并需要由指定的列完成(在本例中为date),结果行必须包含原始数组中的所有关联键。

代码语言:javascript
复制
$array = [
    [
        ['date' => '2011-01-17', 'col-1' => 58, 'col-2' => 54],
        ['date' => '2011-01-19', 'col-1' => 50, 'col-2' => 61],
        ['date' => '2011-01-20', 'col-1' => 44, 'col-2' => 22],
        ['date' => null, 'col-1' => 448, 'col-2' => 196],
    ],
    [
        ['date' => '2011-01-17', 'col-3' => 1489],
        ['date' => '2011-01-18', 'col-3' => 1534],
        ['date' => null, 'col-3' => 1534],
    ]
];

我希望合并与date值相关的数据,确保每行包含所有可能的列,并按日期排序,最后出现空日期行。

期望产出:

代码语言:javascript
复制
array (
  0 => 
  array (
    'date' => '2011-01-17',
    'col-1' => 58,
    'col-2' => 54,
    'col-3' => 1489,
  ),
  1 => 
  array (
    'date' => '2011-01-18',
    'col-1' => NULL,
    'col-2' => NULL,
    'col-3' => 1534,
  ),
  2 => 
  array (
    'date' => '2011-01-19',
    'col-1' => 50,
    'col-2' => 61,
    'col-3' => NULL,
  ),
  3 => 
  array (
    'date' => '2011-01-20',
    'col-1' => 44,
    'col-2' => 22,
    'col-3' => NULL,
  ),
  4 => 
  array (
    'date' => NULL,
    'col-1' => 448,
    'col-2' => 196,
    'col-3' => 1534,
  ),
)

补充说明:

  • 输入数组的计数可能大于2。
  • 子数组可能有不同的环数,并且与它们的索引不相关。
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-01-20 14:46:28

首先,我将假设您的数据是按日期排序的,因为您可以在SQL中进行排序,并且在示例中对其进行排序。您需要在同一时间遍历您的所有集合,合并在一起。

代码语言:javascript
复制
$merged = array();
$i_first = 0;
$i_second = 0;

$count_first = count($data[0]);
$cound_second = count($data[1]);

while ($i_first < $count_first || $i_second < $count_second)
{
    // this comparison depends on what your merge_by is
    $diff = strtotime($data[$i_first]['date']) - strtotime($data[$i_second]['date']);

    if ($diff == 0)
    {
        $merged[] = array_merge($data[$i_first], $data[$i_second]);
        $i_first++;
        $i_second++;
    }
    elseif ($diff < 0) // first date is earlier
    {
        $i_first++;
    }
    else  // second date earlier
    {
        $i_second++;
    }
}

现在,您的$merged数组应该有您想要的东西。请注意,此解决方案假定在一个块中没有重复的日期行,否则它将覆盖现有的结果。此外,如果需要的话,可以扩展到有两个以上的数据集。

票数 1
EN

Stack Overflow用户

发布于 2022-09-16 21:50:28

  1. 填充一个默认值数组,以确保行将包含所有预期列的空值,方法是使用两轮扁平技术,然后将所有键映射为空值以供以后使用。
  2. 使用嵌套循环访问并将数据行推送到结果数组中。使用临时第一级键标识唯一的日期组。为了帮助以后对行进行排序,在定义第一级键时,使用Elvis运算符(?:)返回到文字字符串‘date’--所有其他日期值都将在该键之前按字母顺序排序。
  3. 在迭代时,如果当前行包含以前从未遇到的日期,则用其值覆盖默认值,并将该数据推入该组的行。如果当前行包含以前遇到的日期,则用新数据覆盖缓存的组数据。
  4. 循环之后,根据数组的第一级键对数组进行排序。
  5. 若要删除临时的第一级键,请调用array_values()

代码:(演示)

代码语言:javascript
复制
$defaults = array_map(
    fn() => null,
    array_merge(...array_merge(...$array))
);

$result = [];
foreach ($array as $set) {
    foreach ($set as $row) {
        $key = $row['date'] ?: 'last';
        $result[$key] = array_replace($result[$key] ?? $defaults, $row);
    }
}
ksort($result);
var_export(array_values($result));
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4748292

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档