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


Open two CSV files, compare and add them to an array

我试图从两个不同的两个CSV文件获取信息,并将它们添加到数组中。我所做的就是打开第一个文件,把它的内容作为字符串放入数组。接下来就是棘手的部分了。这两个文件都有一个共同的ID字段,因此只要ID匹配,就必须将其纳入数组。

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

代码如下:

$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给我。

从你的代码我假设:

  • 对于包含山脉数据的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
        )
)

如果我理解正确的话,您正试图根据两个csv文件的id获得它们之间的交集

为了最大限度地减少遇到内存问题的机会,您需要做的是:

在您想要比较的文件中获取并构建一个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;
    }
}

该方法避免了必须将两个文件中的所有数据表示为数组。

这可能比需要的要多一点,但它对我来说很有效。

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);