json с многомерным массивом в csv, где дочерние элементы также имеют родительское значение

#php #arrays #json #csv

#php #массивы #json #csv-файл

Вопрос:

Я пытаюсь разобрать файл json в csv, проблема возникает, когда я сталкиваюсь с многомерным массивом с родительскими элементами — мне нужно, чтобы каждый дочерний элемент этого родительского массива был отдельной строкой в csv со значениями родителей.

Проблема возникает, когда я пытаюсь перебирать дочерние элементы и не могу получить доступ к родительским значениям — я подумываю о создании объединенной строки перед циклическим преобразованием данных, а затем печатаю строку данные для каждого значения, но это похоже на взлом. Кто-нибудь знает лучший способ решить эту проблему?

   [0]=>
  array(7) {
    ["platform"]=>
    string(7) "web"
    ["date"]=>
    string(10) "2019-04-17"
    ["name"]=>
    string(42) "something.com"
    ["data"]=>
    array(10) {
      [0]=>
      array(2) {
        ["revenue"]=>
        float(0.02)
        ["countryCode"]=>
        string(2) "AU"
      }
      [1]=>
      array(2) {
        ["revenue"]=>
        float(0.03)
        ["countryCode"]=>
        string(2) "BE"
      }
      [2]=>
      array(2) {
        ["revenue"]=>
        float(0.02)
        ["countryCode"]=>
        string(2) "CH"
      }
      [3]=>
      array(2) {
        ["revenue"]=>
        float(0.01)
        ["countryCode"]=>
        string(2) "CZ"
      }
      [4]=>
      array(2) {
        ["revenue"]=>
        float(0.34)
        ["countryCode"]=>
        string(2) "GB"
      }
      [5]=>
      array(2) {
        ["revenue"]=>
        float(0.03)
        ["countryCode"]=>
        string(2) "NL"
      }
      [6]=>
      array(2) {
        ["revenue"]=>
        float(0.01)
        ["countryCode"]=>
        string(2) "NO"
      }
      [7]=>
      array(2) {
        ["revenue"]=>
        float(0.01)
        ["countryCode"]=>
        string(2) "NZ"
      }
      [8]=>
      array(2) {
        ["revenue"]=>
        float(0.03)
        ["countryCode"]=>
        string(2) "SE"
      }
      [9]=>
      array(2) {
        ["revenue"]=>
        float(2.46)
        ["countryCode"]=>
        string(2) "US"
      }
    }
  }
[1]=>
  array(7) {
    ["platform"]=>
    string(7) "web"
    ["date"]=>
    string(10) "2019-04-17"
    ["name"]=>
    string(42) "something-else.com"
    ["data"]=>
    array(10) {
      [0]=>
      array(2) {
        ["revenue"]=>
        float(0.72)
        ["countryCode"]=>
        string(2) "AU"
      }
      [1]=>
      array(2) {
        ["revenue"]=>
        float(12.03)
        ["countryCode"]=>
        string(2) "BE"
      }
      [2]=>
      array(2) {
        ["revenue"]=>
        float(0.27)
        ["countryCode"]=>
        string(2) "CH"
      }
      [3]=>
      array(2) {
        ["revenue"]=>
        float(8.71)
        ["countryCode"]=>
        string(2) "CZ"
      }
    }
  }
 

Я хочу, чтобы он был преобразован в :

 platform,date,name,revenue,countryCode
"web","2019-04-17","something.com",0.02,"AU"
"web","2019-04-17","something.com",0.03,"BE"
"web","2019-04-17","something.com",0.02,"CH"
"web","2019-04-17","something.com",0.01,"CZ"
"web","2019-04-17","something.com",0.34,"GB"
...
 

Удалось заставить это работать:

             $f = fopen('examlple.csv', 'w');

            $firstLineKeys = false;

            foreach ($array as $line)
            {
                if (empty($firstLineKeys))
                {
                    $firstLineKeys = array_keys($line);
                            array_pop($firstLineKeys); //removing data as we will loop over it later, and adding the 2 data keys that will be in the results.
                            $firstLineKeys[] = "country";
                            $firstLineKeys[] = "revenue";
                    fputcsv($f, $firstLineKeys);
                    $firstLineKeys = array_flip($firstLineKeys);
                }
                $line_array = array($line);
                $string = array();
                    foreach ($line as $key => $value)
                {
                        if($key !== "data"){
                            $string[]= $value;
                        }else{
                            foreach($value as $country){
                            $new_string = $string;
                            $new_string[]=$country['countryCode'];
                            $new_string[]=$country['revenue'];
                            fputcsv($f, $new_string);
                            }
                        }
                        array_push($line_array,$value);
                }
            }
 

Но мне интересно, есть ли лучший способ сделать это.

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

1. Вы что-нибудь пробовали? Если да, можете ли вы продемонстрировать свои усилия? иначе, exit();

2. добавлен код в вопросе — сейчас он работает, но мне интересно, есть ли лучший способ сделать то, что я пытаюсь сделать.

3. эй, не могли бы вы добавить файл example.json.

Ответ №1:

Я создал массив, как показано ниже, пожалуйста, проверьте, поможет ли это вам:

         $final = array();
        $i = 0;
        $f = array();
        echo '<pre>';
        foreach($arr as $ar) {
            $final[$i] = array(
                'platform' => $ar['platform'],
                'date' => $ar['date'],
                'name' => $ar['name'],
            );                
            foreach($ar['data'] as $key => $value) {                    
                $f[] = array_merge($final[$i], $value);
            }                
            $i  ;
        }
        print_r($f);
        die;
 

пример:

 $arr = array(
            array(
                'platform' => 'web',
                'date' => 'web',
                'name' => 'web',
                'data' => array(
                    array(
                        'revenue' => '0.02',
                        'countryCode' => 'AU',
                    ),
                    array(
                        'revenue' => '0.02',
                        'countryCode' => 'AU',
                    ),
                    array(
                        'revenue' => '0.02',
                        'countryCode' => 'AU',
                    ),
                    array(
                        'revenue' => '0.02',
                        'countryCode' => 'AU',
                    ),
                )
            ),
            array(
                'platform' => 'web1',
                'date' => 'web',
                'name' => 'web',
                'data' => array(
                    array(
                        'revenue' => '0.0211',
                        'countryCode' => 'AU11',
                    ),
                    array(
                        'revenue' => '0.02',
                        'countryCode' => 'AU12',
                    ),
                    array(
                        'revenue' => '0.02',
                        'countryCode' => 'AU13',
                    ),
                    array(
                        'revenue' => '0.02',
                        'countryCode' => 'AU14',
                    ),
                )
            ),
            array(
                'platform' => 'web2',
                'date' => 'web',
                'name' => 'web',
                'data' => array(
                    array(
                        'revenue' => '0.02',
                        'countryCode' => 'AU21',
                    ),
                    array(
                        'revenue' => '0.02',
                        'countryCode' => 'AU22',
                    ),
                    array(
                        'revenue' => '0.02',
                        'countryCode' => 'AU23',
                    ),
                    array(
                        'revenue' => '0.02',
                        'countryCode' => 'AU24',
                    ),
                )
            ),
            array(
                'platform' => 'web3',
                'date' => 'web',
                'name' => 'web',
                'data' => array(
                    array(
                        'revenue' => '0.02',
                        'countryCode' => 'AU31',
                    ),
                    array(
                        'revenue' => '0.02',
                        'countryCode' => 'AU32',
                    ),
                    array(
                        'revenue' => '0.02',
                        'countryCode' => 'AU33',
                    ),
                    array(
                        'revenue' => '0.02',
                        'countryCode' => 'AU34',
                    ),
                )
            )
        );

        $final = array();
        $i = 0;
        $f = array();
        echo '<pre>';
        foreach($arr as $ar) {
            $final[$i] = array(
                'platform' => $ar['platform'],
                'date' => $ar['date'],
                'name' => $ar['name'],
            );                
            foreach($ar['data'] as $key => $value) {                    
                $f[] = array_merge($final[$i], $value);
            }                
            $i  ;
        }
        print_r($f);
        die;