0

我正在尝试从两个不同的两个 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给我......

4

3 回答 3

1

根据您的代码,我假设:

  • 对于包含山脉数据的 CSV 文件:id 位于位置 2,名称位于 0 ,国家位于 1
  • 对于带有坐标的 CSV 文件:id 为 1,纬度为 7,经度为 8

我决定为您提供一个更全面的代码片段,该代码片段适用于任意数量的 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);

使用以下文件:

山.csv

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

坐标.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
        )
)
于 2013-05-29T21:25:12.697 回答
0

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

你要做的就是尽量减少遇到内存问题的机会。

id获取并构建您想要比较的文件中的 s 数组。一个简单的fopenthenfgetcsv循环调用应该可以工作。

$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;
    }
}

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

于 2013-05-29T20:55:31.260 回答
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);
于 2013-05-29T20:57:49.910 回答