【问题标题】:Merging CSV lines where column value is the same合并列值相同的 CSV 行
【发布时间】:2014-10-07 22:44:15
【问题描述】:

我有一个大约 30 列和 2.5K 行的大 CSV 文件。

除了某些列之外,某些行的值完全相同。

我想合并那些相似的,并在不同的列的值之间用逗号连接。

小例子:

id  name  age  kid
1   Tom   40   John
1   Tom   40   Roger
---merged becomes---
1   Tom   40   John, Roger

我可以使用 PHP 使用大量的 fors 和 ifs 来做到这一点,但我希望有一种更优雅、更快速的方法。

【问题讨论】:

  • 请与我们分享您的尝试。
  • @JayBlanchard 请阅读我帖子的最后一行。
  • 我阅读了最后一行,但它并没有展示您尝试过的内容。您是否考虑过在查询中这样做?
  • 在查询中执行此操作将是我的最后一个选择,因为我获得了 CSV 但无法访问数据库。没有什么可尝试的,它只是 csv 中的一个 foreach 行,创建对象,比较字段中的值,将数据添加到对象的属性中,它与以前的属性不同,但主 id 是相同的。 (我已经创建了存储数据的类)

标签: php csv


【解决方案1】:

对于常见的编程问题,这是一个很好的初学者问题。你要做的是一个两步的方法。首先,将 CSV 解析为您可以轻松修改的数据结构,然后遍历该结构并生成与输出匹配的新数组。

<?php

// Parse CSV into rows like:
$rows = array(
    array(
        'id'   => 1,
        'name' => 'Tom',
        'age'  => 50,
        'kid'  => 'John'
    ),
    array(
        'id'   => 1,
        'name' => 'Tom',
        'age'  => 50,
        'kid'  => 'Roger'
    ),
    array(
        'id'   => 2,
        'name' => 'Pete',
        'age'  => 40,
        'kid'  => 'Pete Jr.'
    ),
);

// Array for output
$concatenated = array();

// Key to organize over
$sortKey = 'id';

// Key to concatenate
$concatenateKey = 'kid';

// Separator string
$separator = ', ';

foreach($rows as $row) {

    // Guard against invalid rows
    if (!isset($row[$sortKey]) || !isset($row[$concatenateKey])) {
        continue;
    }

    // Current identifier
    $identifier = $row[$sortKey];

    if (!isset($concatenated[$identifier])) {
        // If no matching row has been found yet, create a new item in the
        // concatenated output array
        $concatenated[$identifier] = $row;
    } else {
        // An array has already been set, append the concatenate value
        $concatenated[$identifier][$concatenateKey] .= $separator . $row[$concatenateKey];
    }
}

// Do something useful with the output
var_dump($concatenated);

【讨论】:

  • 正是我完成这项工作所需要的。我不得不添加更多的连接键和条件,但它工作得很好。谢谢!
【解决方案2】:

如果您只有 CSV 文件中的数据,我认为最简单的方法是使用公共数据作为键构建关联数组并在存在时对其进行修改:

$array=[];
while ($a=fgetcsv($handle)){
   if (isset($array[$a[0]."-".$a[1]."-".$a[2]])) {
      $array[$a[0]."-".$a[1]."-".$a[2]].=",".$a[3];
   }
   else {
      $array[$a[0]."-".$a[1]."-".$a[2]]=$a[3];
   }
}

【讨论】:

  • 感谢您抽出宝贵时间,但我在另一个答案(naneau's)中找到了解决方案
猜你喜欢
  • 2023-03-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多