2

I have this associative array with a key "key1" and another "key2":

{   
   id   :   1,
   name : "Rob",
   key1 : "bla"
},
{   
   id   :   2,
   name : "Mat",
   key1 : "blabla"
},
{   
   id   :   3,
   name : "Tom",
   key2 : "blablabla"
}
  

this is my code for write the csv file:

    // $csv is the array

    $fp = fopen('file.csv', 'wb');

    foreach ($csv as $fields) {
        fputcsv($fp, $fields);
    }

    fclose($fp);

result is something like. All the information in line:

1,Rob,bla
2,Mat,blabla
3,Tom,blablabla

Is there a way to write these values in the column based on their key? The result should be:

id  |  name  |  key1    |   key2
1   |  Rob   |  bla     |
2   |  Mat   |  blabla  |
3   |  Tom   |          |  blablabla

2 Answers 2

2

You can do this with a loop saving all your table keys. Then you check all the keys on each line, if the key is missing, create it with an empty string !

$fp = fopen('file.csv', 'wb');
$savedKeys = [] ;
foreach ($csv as $getKey) {
$savedKeys = array_merge($savedKeys,array_keys($getKey)) ;
}

$savedKeys =array_unique($savedKeys) ;

foreach ($csv as $fields) {

    foreach ($savedKeys AS $checkKey){
        if (!isset($field[$checkKey])){
            $field[$checkKey] = '';
        }
    }
    fputcsv($fp, $fields);
}

fclose($fp);
Sign up to request clarification or add additional context in comments.

1 Comment

In my case, I wanted to have the header in the CSV. So I had to write to the CSV after $savedKeys where unique: fputcsv($fp, $savedKeys, $separator = ";", $enclosure = "\""); The data-fputcsv then accordingly.
0

I also needed this, and implemented as follows:

<?php

class DisparateRowAlignerTest extends TestCase {

  public function test_aligning_disparate_rows() {
    $this->assertEquals(
      [
        ['foo', 'bar', 'baz', 'zip'],
        [1, '', '', ''],
        [2, 3, '', ''],
        ['', 5, 4, ''],
        [6, '', 7, ''],
        ['', '', '', 8],
        ['', '', '', ''],
      ],
      DisparateRowAligner::alignRows([
        ['foo' => 1],
        ['foo' => 2, 'bar' => 3],
        ['baz' => 4, 'bar' => 5],
        ['foo' => 6, 'baz' => 7],
        ['zip'=> 8],
        [],
      ])
    );
  }

}

class DisparateRowAligner {

  /**
   * @param array<array<string, mixed>> $rows
   */
  public static function alignRows(
    array $rows,
    ?string $emptyFill = ''
  ): array {
    $keys = static::getKeys($rows);
    return [
      $keys,
      ...array_map(
        fn (array $oldRow) => array_map(
          fn (string $key) => $oldRow[$key] ?? $emptyFill,
          $keys
        ),
        $rows
      ),
    ];
  }

  private static function getKeys(array $rows): array {
    return array_values(
      array_unique(
        array_reduce(
          $rows,
          fn (array $keys, array $row) => array_merge($keys, array_keys($row)),
          []
        )
      )
    );
  }

}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.