打开两个CSV文件,比较并将它们添加到数组中

时间:2013-05-29 20:30:24

标签: php arrays csv

我正在尝试从两个不同的两个CSV文件中获取信息并将它们添加到数组中。我做的基本上是打开第一个文件,将其内容作为字符串输入数组。然后在这里它是棘手的部分。这两个文件都有一个共同的ID字段,因此每当ID匹配时,它必须被带入数组。

我试图以两种不同的方式做到这一点,打开一个文件,在另一个文件中打开另一个文件,比较并保存到数组中。另一种方法是从两个文件中获取所有信息到两个separe数组,然后找到匹配并将它们转换为第三个数组。

以下是代码:

$handle0 = \fopen("/Data/mountain1.csv", "r");

if ($handle0) {
    $line0 = 0;
    while (($buffer0 = fgets($handle0, 4000)) !== false) {
        if ($line0 > 0){
            $mountainArray = str_getcsv($buffer0, ",");                 
            $obj = array();
            $obj["id"] = $mountainArray[2];
            $obj["name"] = $mountainArray[0];
            $obj["country"] = $mountainArray[1];

            $handle1 = fopen("/Data/mountain1.csv", "r");
            if ($handle1) {
                $line1 = 0;
                while (($buffer1 = fgets($handle1, 4000)) !== false) {
                    if ($line1 > 0) {
                        $latlonArray = str_getcsv($buffer1, ",");
                        $content = array();
                        $content["id"] = $latlonArray[1];
                        if ((int)$content["id"] == (int)$obj["id"]) {
                            $obj["latitude"] = $latlonArray[7];
                            $obj["longitude"] = $latlonArray[8];
                        }
                    $line1++;
                    }
                }
                fclose($handle1);
            }

            $mountain[] = $obj;
        }
        $line0++;
    }
    fclose($handle0);
}

此代码只是循环而不执行任何操作

if ($handle0) {
    while (($buffer0 = fgets($handle0, 4000)) !== false) {
        $mountainArray = str_getcsv($buffer0, ",");
        $content0 = array();
        $content0["id"] = $mountainArray[2];
        $content0["name"] = $mountainArray[0];
        $content0["country"] = $mountainArray[1];

        $mountain[] = $content0;
    }
    fclose($handle0);
}

if ($handle1) {
    while (($buffer1 = fgets($handle1, 4000)) !== false) {
        $latlonArray = str_getcsv($handle1, ",");
        $content1 = array();
        $content1["id"] = $latlonArray[1];
        $content1["latitude"] = $latlonArray[7];
        $content1["longitude"] = $latlonArray[8];

        $latlon[] = $content1;
    }
    fclose($handle1);
}

foreach ($mountain as $row0) {
    $obj = array();
    $obj["id"] = $row0["productUid"];
    $obj["name"] = $row0["name"];
    $obj["country"] = $row0["address"];

    foreach ($latlon as $row1) {
        if((int)$row1["id"] == (int)$row0["id"]) {
            $obj["latitude"] = $row1["latitude"];
            $obj["longitude"] = $row1["longitude"];
        }
    }

    $mountains[] = $obj;
}

并且这个只是给我返回null ...

3 个答案:

答案 0 :(得分:1)

  

从你的代码中我假设:

     
      
  • 对于包含山脉数据的CSV文件: ID位于第2位,名称位于0,国家/地区位于1
  •   
  • 对于坐标为 id为1,纬度为7,经度为8
  • 的CSV文件。   

我决定为您提供更完整的代码段,该代码段适用于任意数量的CSV文件,您只需将它们添加到$csvFiles数组中,并使用文件名作为键和文件类型作为值

<?php
$result   = array();
$csvFiles = array(
    'mountains.csv'   => 'Mountain',
    'coordinates.csv' => 'Coordinate'
);

foreach ($csvFiles as $csvFile => $type) {
    if ($handle = fopen($csvFile, 'r')) {
        $lineNumber = 0;

        while ($data = fgetcsv($handle, 128, ',')) {
            if (!$lineNumber) {
                $lineNumber++;
                continue;
            }

            switch ($type) {
                // Store the record in the result array
                case 'Mountain':
                    $record = array(
                        'id'      => $data[2],
                        'name'    => $data[0],
                        'country' => $data[1]
                    );

                    $id          = $record['id'];
                    $result[$id] = $record;
                    break;

                // Add longitude and latitude to the record
                // if already in the result array
                case 'Coordinate':
                    $record = array(
                        'id'        => $data[1],
                        'latitude'  => $data[7],
                        'longitude' => $data[8]
                    );

                    $id = $record['id'];
                    if (!empty($result[$id])) {
                        $result[$id] = array_merge($result[$id], $record);
                    }
                    break;
            }
        }
    }
}

print_r($result);

使用以下文件:

mountains.csv

# CSV headers
aaa, USA, 1
aab, Canada, 2
aac, USA, 3
bbb, Portugal, 4
ccc, Germany, 5

coordinates.csv

# CSV headers
asd, 1, asd, asd, asd, asd, asd, 10.00, 20.00
asd, 2, asd, asd, asd, asd, asd, 1.00, 2.00
asd, 4, asd, asd, asd, asd, asd, 5.00, 10.00
asd, 3, asd, asd, asd, asd, asd, 2.00, 4.00
asd, 5, asd, asd, asd, asd, asd, 100.00, 200.00

输出将是:

Array
(
    [ 1] => Array
        (
            [id] =>  1
            [name] => aaa
            [country] =>  USA
            [latitude] =>  10.00
            [longitude] =>  20.00
        )

    [ 2] => Array
        (
            [id] =>  2
            [name] => aab
            [country] =>  Canada
            [latitude] =>  1.00
            [longitude] =>  2.00
        )

    [ 3] => Array
        (
            [id] =>  3
            [name] => aac
            [country] =>  USA
            [latitude] =>  2.00
            [longitude] =>  4.00
        )

    [ 4] => Array
        (
            [id] =>  4
            [name] => bbb
            [country] =>  Portugal
            [latitude] =>  5.00
            [longitude] =>  10.00
        )

    [ 5] => Array
        (
            [id] =>  5
            [name] => ccc
            [country] =>  Germany
            [latitude] =>  100.00
            [longitude] =>  200.00
        )
)

答案 1 :(得分:0)

如果我理解正确,您正试图根据其ID

获取两个csv文件之间的交集

你想要做的是尽量减少遇到内存问题的可能性。

在您想要比较的文件中构建id的数组。一个简单的fopen然后在循环中调用fgetcsv应该有效。

$ids = array();
$fp = fopen($file1, "r");
while ($row = fgetcsv($fp)){
    // assuming first field contains the id
    $ids[$row[0]] = "";
} 
fclose($fp);

打开您要比较的文件并通过相同的fopen,fgetcsv循环,但检查您在步骤1中构建的列表中是否存在每个ID。然后,如果它在列表中,则将其添加到结果中。

$results = array();
$fp = fopen($file2, "r");
while ($row = fgetcsv($fp)){
    if (isset($ids[$row[0])){
          $results[] = $row;
    }
}

此方法避免必须将任一文件中的所有数据表示为数组。

答案 2 :(得分:0)

这可能比需要的多一点,但它对我有用。

<强> csv1.csv

id,val
0,cat
1,dog

<强> csv2.csv

id,val
2,brid
1,cat

PHP

<?php
header("content-type: text/plain");
$array = [];
$i = 0;
$csv1 = "csv1.csv";
$csv2 = "csv2.csv";

// Load file 1 into an array
// Skip row 1
if (($handle = fopen($csv1, "r")) !== FALSE){
    while (($data = fgetcsv($handle)) !== FALSE){
        if($i == 0){$i++; continue;}
        $array[] = $data;
        $i++;
    }
    fclose($handle);
}

$i = 0;
// Load file 2 into the array if the values don't exist
// Skip row 1
if (($handle = fopen($csv2, "r")) !== FALSE){
    while (($data = fgetcsv($handle)) !== FALSE){
        if($i == 0){$i++; continue;}
        $inarray = false;
        foreach($array as $itm){
            if(in_array($data[0], $itm)){
                $inarray = true;
                break;
            }
        }
        if(!$inarray){
            $array[] = $data;
        }
        $i++;
    }
    fclose($handle);
}


print_r($array);