使用 PHP 在两个 csv 文件之间实现左连接

2024-02-18

由于该解决方案是根据投票良好的答案改编的别处 https://stackoverflow.com/a/25837426,我没想到会遇到问题。

问题:我想要LEFT JOIN 文件0.csv https://www.dropbox.com/s/gx1oyfj03dsn45p/file0.csv?dl=0 with 文件1.csv https://www.dropbox.com/s/40zndvtmm2azctg/file1.csv?dl=0.

文件0.csv

+-----------------+-------------+--------------+
| Manufacturer ID |    image    | description  |
+-----------------+-------------+--------------+
| SKU231          | image1.jpg  | A box.       |
| SKUAG1          | image22.jpg | Another box. |
| SKU21D          | image7a.png | A third box. |
+-----------------+-------------+--------------+

文件1.csv:

+--------+--------+--------+-------+-------+
|  mpn   | length | height | width | title |
+--------+--------+--------+-------+-------+
| SKU231 |     22 |     14 |    10 | Box 1 |
| SKUAG1 |     12 |      6 |     6 | Box 2 |
| SKU21D |      5 |      8 |     5 | Box 3 |
+--------+--------+--------+-------+-------+

期望的结果(file2.csv):

+-----------------+-------------+--------------+--------+--------+--------+-------+-------+
| Manufacturer ID |    image    | description  |  mpn   | length | height | width | title |
+-----------------+-------------+--------------+--------+--------+--------+-------+-------+
| SKU231          | image1.jpg  | A box.       | SKU231 |     22 |     14 |    10 | Box 1 |
| SKUAG1          | image22.jpg | Another box. | SKUAG1 |     12 |      6 |     6 | Box 2 |
| SKU21D          | image7a.png | A third box. | SKU21D |      5 |      8 |     5 | Box 3 |
+-----------------+-------------+--------------+--------+--------+--------+-------+-------+

PHP 函数LEFT JOIN file0.csv with file1.csv on Manufacturer ID and mpn分别:

function my_csv_join(array $csv_input_file_array, $csv_output_file, $html_preview, $left_join_on, $right_join_on = NULL) {
    if (count($csv_input_file_array) > 2) {
        echo 'This function probably only works for 2 csv files being joined at a time.  Reapply iteratively if needed.  Exiting now.';
        exit;
    } else {
        for ($x = 0; $x <= 1; $x++) {
            //get csv file to array 
            ${'file' . $x} = fopen($csv_input_file_array[$x], "r"); //Dynamic variables using braces: https://stackoverflow.com/a/9257536/9095603
    
            while (!feof(${'file' . $x})) {
                ${'csv_array' . $x}[] = fgetcsv(${'file' . $x});
            }
            fclose(${'file' . $x});
    
            ${'csv_array' . $x} = array_filter(${'csv_array' . $x}); // gets rid of last empty array in case present
            //CREATE HEADERED ARRAY
            ${'header' . $x} = array_shift(${'csv_array' . $x});
            foreach (${'csv_array' . $x} as ${'product_data_array' . $x} {
                ${'headered_array' . $x}[] = array_combine(${'header' . $x}, ${'product_data_array' . $x});
            }        
        }
        // How to simulate the SQL LEFT JOIN operation using PHP arrays?  https://stackoverflow.com/a/25837426

        //function to simulate the left join
        $left = $headered_array0;
        $right = $headered_array1;
        $final = array();

        if (empty($right_join_on)) // if $right_join_on omitted implies $right_join_on has the same value as $left_join_on
            $right_join_on = $left_join_on;
        foreach ($left AS $k => $v) {
            $final[$k] = $v; //basically keeping everything; $left just becomes $final
            foreach ($right AS $kk => $vv) {
                if ($v[$left_join_on] == $vv[$right_join_on]) { 
                    foreach ($vv AS $key => $val)
                        $final[$k][$key] = $val; 
                } else {
                    foreach ($vv AS $key => $val)
                   $final[$k][$key] = NULL; 
                }
            }
        }
        if ($html_preview == 'y') {
            echo '<pre>';
                var_dump($final);
            echo '</pre>';
        }
    
        // REINSTATE HEADERS
        // var_dump($final[0]);
        $indented_header = array(
            0 => array_keys($final[0])
        );
        $re_headered_array = array_merge($indented_header, $final);
    
        // write array to csv file
        $file2 = fopen($csv_output_file, "w");
        foreach ($re_headered_array as $line) {
            fputcsv($file2, $line);
        }
    
        fclose($file2);
    }
}

调用函数my_csv_join():

my_csv_join(array('C:\xampp\htdocs\kalugi\file0.csv','C:\xampp\htdocs\kalugi\file1.csv'), 'C:\xampp\htdocs\kalugi\file2.csv','y','Manufacturer ID','mpn');

实际结果显示并非所有记录都匹配file0."Manufacturer ID" = file1.mpn正在匹配中。因此,一些满足连接条件的预期行未连接。我们有NULL代替他们的价值观:

var_dump结果:

array(3) {
  [0]=>
  array(8) {
    ["Manufacturer ID"]=>
    string(6) "SKU231"
    ["image"]=>
    string(10) "image1.jpg"
    ["description"]=>
    string(6) "A box."
    ["mpn"]=>
    NULL
    ["length"]=>
    NULL
    ["height"]=>
    NULL
    ["width"]=>
    NULL
    ["title"]=>
    NULL
  }
  [1]=>
  array(8) {
    ["Manufacturer ID"]=>
    string(6) "SKUAG1"
    ["image"]=>
    string(11) "image22.jpg"
    ["description"]=>
    string(12) "Another box."
    ["mpn"]=>
    NULL
    ["length"]=>
    NULL
    ["height"]=>
    NULL
    ["width"]=>
    NULL
    ["title"]=>
    NULL
  }
  [2]=>
  array(8) {
    ["Manufacturer ID"]=>
    string(6) "SKU21D"
    ["image"]=>
    string(11) "image7a.png"
    ["description"]=>
    string(12) "A third box."
    ["mpn"]=>
    string(6) "SKU21D"
    ["length"]=>
    string(1) "5"
    ["height"]=>
    string(1) "8"
    ["width"]=>
    string(1) "5"
    ["title"]=>
    string(5) "Box 3"
  }
}

结果写入 $file2 (file2.csv):


    +-----------------+-------------+--------------+--------+--------+--------+-------+-------+
    | Manufacturer ID |    image    | description  |  mpn   | length | height | width | title |
    +-----------------+-------------+--------------+--------+--------+--------+-------+-------+
    | SKU231          | image1.jpg  | A box.       |        |        |        |       |       |
    | SKUAG1          | image22.jpg | Another box. |        |        |        |       |       |
    | SKU21D          | image7a.png | A third box. | SKU21D |      5 |      8 |     5 | Box 3 |
    +-----------------+-------------+--------------+--------+--------+--------+-------+-------+
  

尽管有 2 行没有连接,但为什么file0."Manufacturer ID" = file1.mpn满意吗?


我将把它简化为SSCCE http://sscce.org/所以很容易理解和重现。

我认为你在这里的解决方案过于复杂,这可能是导致你出现这么多奇怪错误的原因。解决方案实际上相当简单。您需要做的就是获取每个 csv 文件,将其解析为行和列,然后将每一行合并为一行,以将其写回另一个 csv。

这是最简单的方法:

$file0 = <<<'FILE0'
Manufacturer ID,image,description
SKU231,image1.jpg,A box.
SKUAG1,image22.jpg,Another box.
SKU21D,image7a.png,A third box.
FILE0;

$file1 = <<<'FILE1'
mpn,length,height,width,title
SKU231,22,14,10,Box 1
SKUAG1,12,6,6,Box 2
SKU21D,5,8,5,Box 3
FILE1;

$csv1 = array_map('str_getcsv', explode("\n", $file0));
$csv2 = array_map('str_getcsv', explode("\n", $file1));

$fd = fopen("/tmp/test.csv", 'w');


foreach ($csv1 as $row => $columns) {

    $newRow = array_merge($columns, $csv2[$row]);
    fputcsv($fd, $newRow);

}

$fd = fopen("/tmp/test.csv", "r");

while (($line = fgets($fd)) !== false) {
    echo $line;
}

结果:



"Manufacturer ID",image,description,mpn,length,height,width,title
SKU231,image1.jpg,"A box.",SKU231,22,14,10,"Box 1"
SKUAG1,image22.jpg,"Another box.",SKUAG1,12,6,6,"Box 2"
SKU21D,image7a.png,"A third box.",SKU21D,5,8,5,"Box 3"
  



|Manufacturer ID | image       | description  | mpn    | length | height | width | title |
|----------------|-------------|--------------|--------|--------|--------|-------|-------|
| SKU231         | image1.jpg  | A box.       | SKU231 | 22     | 14     | 10    | Box 1 |
| SKUAG1         | image22.jpg | Another box. | SKUAG1 | 12     | 6      | 6     | Box 2 |
| SKU21D         | image7a.png | A third box. | SKU21D | 5      | 8      | 5     | Box 3 |
  
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 PHP 在两个 csv 文件之间实现左连接 的相关文章

  • 如何将 CSV 文件读入 .NET 数据表

    如何将 CSV 文件加载到System Data DataTable 根据CSV文件创建数据表 常规 ADO net 功能是否允许这样做 我一直在使用OleDb提供者 但是 如果您正在读取具有数值的行 但希望将它们视为文本 则会出现问题 但
  • gmail 不断阻止 PHPmailer 登录

    我将在接下来的 8 小时内部署一个网站 而 Gmail 刚刚停止接受 PHPmailer 登录我的帐户 起初 它在测试过程中工作了几个小时 然后 它就停止工作了 我已经允许所有允许不太安全的应用程序从 gmail 登录 但它仍然不允许 ph
  • 删除PHP字符串中所有不匹配的字符?

    我有一个文本 我想从中删除所有不属于以下字符的字符 所需字符 0123456789 abcdefghijklmnopqrstuvwxyz n 最后一个是我确实想保留的 n 换行符 要匹配除列出的字符之外的所有字符 请使用反转字符集 http
  • 优雅地处理没有数据的 amcharts

    我想知道我的 dataProvider 是否为空 amCharts绘制时默认为null 我怎样才能动态地处理它 var chart AmCharts makeChart chartdiv theme none type serial dat
  • 单词之间没有空格的语言(例如亚洲语言)中的断词?

    我想让 MySQL 全文搜索适用于日语和中文文本以及任何其他语言 问题在于这些语言以及可能其他语言通常在单词之间没有空格 当您必须键入与文本中相同的句子时 搜索没有用 我不能只在每个字符之间添加空格 因为英语也必须有效 我想用 PHP 或
  • 如何检查PHP变量是否包含非数字?

    我只是想知道检查 PHP 变量中是否有非数字的方法以及它是否也检测字符之间的空格 需要确保我的表单字段中没有添加任何奇怪的内容 提前致谢 如果您的意思是您只想要一个包含数字的值 那么您可以使用ctype digit http php net
  • PHP 会话不适用于游戏

    我正在尝试模仿一款名为 SKUNK 用骰子玩 的游戏来完成一项作业 我无法让会话正常工作 这是我第一次使用 PHP 我还被告知无需会议即可完成 这是我的代码
  • Yii 使用 ajax 进行分页

    我需要使用ajax启用分页 我的代码 控制器 更新内容ajax function actionIndex dataProvider new CActiveDataProvider News array pagination gt array
  • 检查 PHP 中“@”字符后面的单词

    我现在正在制作一个新闻和评论系统 但是我已经在一个部分上停留了一段时间了 我希望用户能够在 Twitter 上引用其他玩家的风格 例如 用户名 该脚本看起来像这样 不是真正的 PHP 只是想象脚本 3 string I loved the
  • Woocommerce 让产品显示在存档页面中

    我正在尝试让所有产品显示在我商店的存档页面中 我想知道他们的id我正在使用我的一个钩子 它在 wp head 上运行并检查 if is product category 我想以某种方式访问 产品的查询并获取它们的 ID if is prod
  • PHP严格标准:声明应该兼容

    我有以下类层次结构 class O Base class O extends O Base abstract class A Abstract public function save O Base obj class A extends
  • posts_search 中的自定义查询

    如何使用此查询作为我的自定义搜索查询 add filter posts search my search is perfect 20 2 function my search is perfect search wp query sWord
  • 是否可以使用 PHP 重定向发送 POST 数据?

    更新 这不是重复的如何使用 PHP 发送 POST 请求 https stackoverflow com questions 5647461 how do i send a post request with php 那里的解决方案对我不起
  • 从 smarty 访问 PHP 文件的变量(本地或全局)

    我有一个 php 文件 其中包含一些本地和全局变量 例如 foo 从此文件中调用 smarty 对象 如何在不更改 PHP 文件的情况下从 smarty 脚本访问 foo Thanks 如果你有一个名为 BASE 的常量变量 并且定义如下
  • 从 .phar 存档中提取文件

    对于 Phar 文件 我完全错过了一些东西 我正在安装一个需要 phpunit pdepend 和其他依赖项的项目 我将它们作为 phar 文件获取 但是 我无法使用命令行工具 php 命令 从中提取文件 我用谷歌搜索了这个问题 但没有发现
  • 为什么 iconv 在 php:7.4-fpm-alpine docker 中返回空字符串

    给出以下代码
  • PHP HEREDoc (EOF) 语法在 Sublime Text 3 上突出显示与正斜杠的差异

    我不熟悉 Sublime Text 3 如何使用语法突出显示 例如 如果它纯粹依赖于主题 或者它内置于主题运行的标准中 但就我而言 使用 PHP 的 HERE 文档和转发存在一些语法突出显示差异斜线 一旦出现正斜杠 ST3 就会认为以下所有
  • php,统计字符并删除超过140个字符的内容

    我需要一个 PHP 函数来计算短语的字符数 如果短语长度超过 140 个字符 则此函数应删除所有其他字符并在短语末尾添加三个点 例如我们有 message I am what I am and you are what you are et
  • Magento - 自定义支付模块

    这是一个非常普遍的问题 但这里是 我正在尝试在 Magento 中创建一个自定义支付模块 我创建了一个 常规 模块 可以连接到 Magento 事件 观察者模型 但是我如何告诉 Magento 将模块视为支付模块 以便它显示在管理后端和结账
  • XSLT 将动态 XML 转换为 CSV 并且 XML 节点不完全重复 II

    我正在尝试创建 XSLT 将 XML 转换为 CSV 这里放置了我的 XML 和预期输出 任何人都知道如何获得以下输出 请优先分享我 我的 XML 是

随机推荐