【问题标题】:Merging two csv files together using php使用php将两个csv文件合并在一起
【发布时间】:2014-10-18 14:31:37
【问题描述】:

我有两组 csv 文件 - 一组包含合同数据,另一组包含已授予的合同。我需要使用公共字段 (contractName) 组合两个 csv 文件并计算已关闭授予合同的总金额。Link to the csv files

到目前为止,我已经设法将两个 csv 文件合并在一起并将其写入 final.csv 文件,但我无法使用公共字段(合同名称)合并这两个 csv 文件。这是代码。`

<?php
$nn = 0;
foreach (glob("*.csv") as $filename) {
    if (($handle = fopen($filename, "r")) !== FALSE) {
        while (($data = fgetcsv($handle, 0, ",")) !== FALSE) {

            $c = count($data);

            for ($x=0;$x<$c;$x++)
            {
                $csvarray[$nn][] = $data[$x];
            }
            $nn++;
        }

        fclose($handle);
    }

}

$fp = fopen('../final.csv', 'w');//output file set here

foreach ($csvarray as $fields) {
    fputcsv($fp, $fields);
}

fclose($fp);?>

这是我的最终输出。

contractName,contractDate,completionDate,awardee,awardeeLocation,Amount
Contract-2070-3,5/9/14,8/25/14,"SK Builders",Banke,200000
Contract-2070-5,3/18/14,4/8/14,"S engineering industries",Makwanpur,300000
Contract-2070-9,3/6/14,4/6/14,"Gourishankar nirman sewa",Lalitpur,400000
Contract-2070-10,2/6/14,6/16/14,"SK Builders",Banke,500000
contractname,status,bidPurchaseDeadline,bidSubmissionDeadline,bidOpeningDate,tenderid,publicationDate,publishedIn
Contract-2070-1,Closed,6/12/14,6/13/14,6/13/14,2070/071/2,5/14/14,"Nagarik Daily"
Contract-2070-2,Closed,6/10/14,6/11/14,6/11/14,16/070/71,5/12/14,"The Himalayan Times"
Contract-2070-3,Current,3/8/14,3/9/14,3/9/14,DDC/Bag/Bridge/03-070/71,3/10/14,"Nagarik Daily"
Contract-2070-4,Current,4/23/14,4/25/14,4/25/14,04(2070/071),4/9/14,"Hetauda sandesh"
Contract-2070-5,Closed,4/23/14,4/25/14,4/26/14,04(2070/071),4/10/14,"Hetauda sandesh"
Contract-2070-6,Current,4/23/14,4/25/14,4/27/14,04(2070/071),4/11/14,"Hetauda sandesh"
Contract-2070-7,Current,4/23/14,4/25/14,4/28/14,04(2070/071),4/12/14,"Hetauda sandesh"
Contract-2070-8,Current,4/23/14,4/25/14,4/29/14,04(2070/071),4/13/14,"Hetauda sandesh"
Contract-2070-9,Closed,2/6/14,2/8/14,2/8/14,15/070/71,1/9/14,"The Himalayan Times"
Contract-2070-10,Current,1/14/14,1/15/14,1/16/14,"13,2070/2071",1/6/14,"The Himalayan Times"

但最终的输出应该是这样的。

contractname,status,bidPurchaseDeadline,bidSubmissionDeadline,bidOpeningDate,tenderid,publicationDate,publishedIn,contractDate,completionDate,awardee,awardeeLocation,Amount 
Contract-2070-1,Closed,6/12/14,6/13/14,6/13/14,2070/071/2,5/14/14,Nagarik Daily,,,,,
Contract-2070-2,Closed,6/10/14,6/11/14,6/11/14,16/070/71,5/12/14,The Himalayan Times,,,,,
Contract-2070-3,Current,3/8/14,3/9/14,3/9/14,DDC/Bag/Bridge/03-070/71,3/10/14,Nagarik Daily,5/9/14,8/25/14,SK Builders,Banke,200000
Contract-2070-4,Current,4/23/14,4/25/14,4/25/14,04(2070/071),4/9/14,Hetauda sandesh,,,,,
Contract-2070-5,Closed,4/23/14,4/25/14,4/26/14,04(2070/071),4/10/14,Hetauda sandesh,3/18/14,4/8/14,S engineering industries,Makwanpur,300000
Contract-2070-6,Current,4/23/14,4/25/14,4/27/14,04(2070/071),4/11/14,Hetauda sandesh,,,,,
Contract-2070-7,Current,4/23/14,4/25/14,4/28/14,04(2070/071),4/12/14,Hetauda sandesh,,,,,
Contract-2070-8,Current,4/23/14,4/25/14,4/29/14,04(2070/071),4/13/14,Hetauda sandesh,,,,,
Contract-2070-9,Closed,2/6/14,2/8/14,2/8/14,15/070/71,1/9/14,The Himalayan Times,3/6/14,4/6/14,Gourishankar nirman sewa,Lalitpur,400000
Contract-2070-10,Current,1/14/14,1/15/14,1/16/14,"13, 2070/2071",1/6/14,The Himalayan Times,2/6/14,6/16/14,SK Builders,Banke,500000

【问题讨论】:

  • 如果命令行实用程序适合你,你可以试试csvkit.readthedocs.org/en/latest/scripts/csvjoin.html
  • @Giovanni 抱歉,有人告诉我不要使用命令行。我需要通过 php 来完成。有没有什么办法。我现在卡住了。
  • @Giovanni 我尝试了 csvkit,它也很方便,但遗憾的是我无法使用它
  • 这是面试题吗?您是否需要展示编写算法或以现实方式解决问题的能力?

标签: php csv


【解决方案1】:

这个问题并不难,你总是可以将数据放在数组中的那些 csv 中并使用它们,就像这个解决方案一样:

// 1st section
        $fh = fopen('awards.csv', 'r');
        $fhg = fopen('contracts.csv', 'r');
         while (($data = fgetcsv($fh, 0, ",")) !== FALSE) {
            $awards[]=$data;
        }
        while (($data = fgetcsv($fhg, 0, ",")) !== FALSE) {
                $contracts[]=$data;
        }
 // 2nd section   
        for($x=0;$x< count($contracts);$x++)
        {
            if($x==0){
                unset($awards[0][0]);
                $line[$x]=array_merge($contracts[0],$awards[0]); //header
            }
            else{
                $deadlook=0;
                for($y=0;$y <= count($awards);$y++)
                {
                    if($awards[$y][0] == $contracts[$x][0]){
                        unset($awards[$y][0]);
                        $line[$x]=array_merge($contracts[$x],$awards[$y]);
                        $deadlook=1;
                    }           
                }
                if($deadlook==0)
                    $line[$x]=$contracts[$x];
            }
        }
  // 3 section     
        $fp = fopen('final.csv', 'w');//output file set here

        foreach ($line as $fields) {
            fputcsv($fp, $fields);
        }
        fclose($fp);

我很难解释代码,因为我来自西班牙国家,所以我的英语不是很好......但我可以试试

基本上代码有3个部分,

在第 1 节中, 打开这两个文件并将内容放入数组 $awards[] 和 $contracts[] 中,因此 $awards[0] 是 Awards.csv 中的第一行,$awards[1] 是 Awards.csv 中的第二行,等等,在 $contracts[] 中也是如此。

在第 2 节中,

我比较每个数组中的第一个单词 $awards[x][0] 和 $contracts[x][0]。

第一个if, if($x==0), 是做标题。 首先,我使用unset函数删除第一个单词contractname,并使用array_merge函数加入$awards[0]和$contracts[0]。

然后,使用for 我从 $contracts 数组中选择每一行中的第一个单词,并与 $awards 数组中每一行中的第一个单词进行比较。 所以,if($awards[$y][0] == $contracts[$x][0]) 检查第一个单词(ej.Contract-2070-3are)是否相同,如果它们是相同的字符串,请将其删除并合并这些行。

如果这些单词不同,则将 $contracts[x] 行保存在 $line 数组中并继续。

在第 3 节中, 将 $line 数组中的内容保存到文件中。

【讨论】:

  • 谢谢你的工作。现在我试图理解代码。非常感谢你。你真棒,天才
  • 你能告诉我如何解决这样的问题吗?我的意思是如何制作算法。我是新手,非常愿意学习
  • 检查一下,如果您有任何问题,我可以尝试解释,但我建议您尝试阅读更多算法和数据结构,请在此处查看这些链接是否对您有帮助 @987654321 @
  • 你的英语比我的好 :D 但相信我你的代码会说话 :D
【解决方案2】:

这是某种面试题吗?您是否需要展示编写算法或以现实方式解决问题的能力?

对于大数据集,我可能只是将 csv 转储到 sqlite db,每个 csv 一个表,然后通过查询将它们连接起来。

或者您可以使用连接字段 (contractName) 作为两个数组的键,使用每个 csv、$contracts 和 $awards 填充两个关联数组。
然后你循环键,并用给定键的每个数组的内容填充一个 $final 数组:

$final = array();
$keys = array_keys($contracts);
foreach($keys as $key) {
    $final[] = array_merge($contracts[$key], $awards[$key]);
}

【讨论】:

  • 这不是面试题。这是我学习算法的一部分,作为菜鸟,我意识到这非常困难。
猜你喜欢
  • 2017-12-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-06-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多