Создание многомерного массива из csv

#php

#php

Вопрос:

У меня возникли проблемы с созданием многомерного массива из файла csv. Мне нужно, чтобы выходные данные были «сгруппированы» по странам, поскольку в каждой стране может быть несколько сетей. Некоторые строки не имеют значения для страны или зоны, поскольку они связаны со строкой над ней. К сожалению, именно так я получаю файл csv, и нет никакого способа изменить выходные данные. Любые отзывы или указания будут оценены.

Фрагмент csv-файла…

 Country|Zone|Network|Video|Voice
Afghanistan,5,Afghan Wireless,No,Yes
,,Roshan,No,Yes
Antigua,4,Digicel,No,Yes
Argentina,5,Telecom Personal,Yes,Yes
,,Movistar,No,Yes
,,Movistar2,Yes,Yes
Aruba,4,Digicel,No
  

Идеальный результат

 Array (
    [0] => Array (
        [country] => Afghanistan
        [zone] => 5
        [network] => Array (
            [0] => Array (
                [name] => Afghan Wireless
                 => No
                [voice] => Yes
            )
            [1] => Array (
                [name] => Roshan
                 => No
                [voice] => Yes
            )
        )
    )
    [1] => Array (
        [country] => Antigua
        [zone] => 4
        [network] => Array (
            [0] => Array (
                [name] => Digicell
                 => No
                [voice] => Yes
            )
        )
    )
    etc...
)
  

Ответ №1:

 <?php 

$csvArray=array();//to store final data 
$networkArray=array();//to serve as temporar buffer

if (($handle = fopen("file.csv", "r")) !== FALSE) 
{
     fgetcsv($handle, 1000, ",");//skip the first line cause contains labels only
    //iterate all ther line 
    while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) 
    { 
        //if a new country
        if($data[0]!=='')
        {  
            /*get last key assigned to the previous country*/
            $key=array_pop(array_keys($csvArray)); 
            /*store the buffer, at the very begining no last country exists 
            so this network will be stored in a null key, will delete it later*/
            $csvArray[$key]['network']=$networkArray; 
            //emty the buffer
            $networkArray=array(); 
            //now we are done with previous country and will store the new one
            $csvArray[]=Array('country'=>$data[0],'zone'=>$data[1]);        
        }//@if ends 
            //Put to buffer network, video and voice
            $networkArray[]=Array('name'=>$data[2],'video'=>$data[3],'voice'=>$data[4]);     
    }//@while ends
    fclose($handle);
}//@outer if ends

//store the last network buffer
$key=array_pop(array_keys($csvArray));  
$csvArray[$key]['network']=$networkArray;   
//delete the null key set in the begining
array_shift($csvArray); 

//show the array
echo '<pre>'; 
print_r($csvArray); 

?>
  

Комментарии:

1. Большое вам спасибо, отлично поработали. И я также узнал немного больше о массиве и циклах.

Ответ №2:

Просто простое решение (не полностью протестированное)

 <?php

// Initialize the final result
$result = array();

// Read the file line by line
$handle = @fopen("test.csv", "r");
if ($handle) {
    $country = null;

    while (($buffer = fgets($handle, 4096)) !== false) {

        $line = explode(',', $buffer);

        if($line[0] == null) {

            $network['name'] = $line[2];
            $network['video'] = $line[3];
            if(isset($line[4])) $network['voice'] = $line[4];

            $country['network'][] = $network;

            $network = null;

        } else {
            if($country != null) {
                $result[] = $country;
                $country = null;
            }

            $country['country'] = $line[0];
            $country['zone'] = $line[1];

            $network['name'] = $line[2];
            $network['video'] = $line[3];
            if(isset($line[4])) $network['voice'] = $line[4];

            $country['network'][] = $network;

            $network = null;

        }

    }
    if (!feof($handle)) {
        echo "Error: unexpected fgets() failn";
    }
    fclose($handle);

    print_r($result);
}