2
\$\begingroup\$

I wrote a function to reduce the size of JSON objects that works simply by turning every associative array into an indexed one, and moving each property's name to the first row of the data array (ordering it a bit like a CSV file, I guess).

<?php

/**
 * Converts a list of associative arrays into indexed arrays.
 *
 * Each property name is collated within an extra array inserted at the beginning
 * of the returned array, structuring the data in a CSV-like fashion. For example:
 *
 *   array(
 *       array('first_name' => 'John',   'last_name' => 'Gardner',   'age' => 28),
 *       array('first_name' => 'Sum',    'last_name' => 'Kunt',      'age' => 25)
 *   )
 *
 * Would be returned as:
 *
 *   array(
 *       array('first_name', 'last_name',    'age'),
 *       array('John',       'Gardner',      28),
 *       array('Sum',        'Kunt',         25)
 *   )
 *
 * Properties are indexed in the order they're encountered when traversing the original data
 * list, with any missing properties assigned empty values if they're present in some rows
 * but absent in others. For instance, consider the following inconsistent data structure,
 * with two rows sharing only partial similarity:
 *
 *   array(
 *       array('first_name' => 'John',   'age' =>  28),
 *       array('first_name' => 'Sum',    'dob' => '1990-08-20')
 *   )
 *
 * These would be collated and returned as:
 *
 *   array(
 *       array('first_name',   'age',    'dob'),
 *       array('John',         '28',      NULL),
 *       array('Sum',           NULL,    '1990-08-20')
 *   )
 *
 * This ensures data will be ordered in a consistent format, and can help reduce latency
 * and bandwidth costs when sending large payloads of JSON-encoded data.
 *
 * @param array $data - A multidimensional array to operate upon
 * @return array
 */
function collate_arrays($data){
    $output     =   array();

    # First, cycle through each row to extract a list of every unique field name that's present.
    $fields     =   array();
    $count      =   0;

    foreach($data as $row){
        foreach($row as $name => $value)
            if(!isset($fields[$name]))
                $fields[$name]  =   $count++;
    }


    # Flip the list of field names and store them in the first row of the returned array.
    $fields     =   array_flip($fields);
    $output[]   =   $fields;


    # Next, run through the array again, ensuring every array and its properties are consistently indexed in running field order.
    foreach($data as $row){
        $indexed_row = array();

        for($i = 0; $i < $count; ++$i)
            $indexed_row[$i] = $row[$fields[$i]];

        $output[]   =   $indexed_row;
    }

    return $output;
}


# Sample use below (with a particularly extreme example)
$messy_array    =   array(
    array('last_name'   => 'Gardner',  'first_name' => 'John',         'dob'           => '1987-04-18',    'age'       =>   28),
    array('first_name'  => 'John',     'last_name'  => 'Gardner',      'age'           =>  28,             'dob'       =>  '1987-04-18'),
    array('first_name'  => 'John',     'last_name'  => 'Gardner',      'age'           =>  28,             'dob'       =>  '1987-04-18'),
    array('first_name'  => 'John',     'last_name'  => 'Gardner',      'age'           =>  28,             'dob'       =>  '1987-04-18'),
    array('age'         =>  28,        'dob'        => '1987-04-18',   'first_name'    => 'John',          'last_name' =>  'Gardner'),
    array(
        'txtFirstName'  => 'John',
        'last_name'     => 'GARDNER',
        'txtLastName'   => 'Gardner',
        'txtAge'        =>  28,
        'dobYear'       =>  1987,
        'dobMonth'      =>  4,
        'dobDay'        =>  18
    ),
    array('first_name'  =>  'John',     'last_name' =>  'Gardner',     'age'    =>  28,     'dob'   => '1987-04-18'),
    array('first_name'  =>  'John',     'last_name' =>  'Gardner',     'age'    =>  28,     'dob'   => '1987-04-18'),
    array('first_name'  =>  'John',     'last_name' =>  'Gardner',                          'dob'   => '1987-04-18'),
    array('first_name'  =>  'John',     'last_name' =>  'Gardner',     'age'    =>  28)
);



header('Content-Type: text/plain; charset=UTF-8');
error_reporting(E_ALL ^ E_NOTICE);

$sorted =   collate_arrays($messy_array);
print_r($sorted);

It works perfectly fine: my issue is I'm not sure I've described the function's purpose clearly enough, or even given it a descriptive-enough name. I've been hit with writer's block so badly, I spent ages writing and rewriting the function's doc-block with no satisfaction.

I'm also worried I might've over-elaborated on the function's purpose, which I had trouble avoiding given its specific nature.

Is there anything unclear, misleading or just plain weird about this function or what it does? I hope I'm just going crazy from looking at my own code for too long...

\$\endgroup\$
  • \$\begingroup\$ Again, your title should be a brief description of what your code does. For example, take a look at the most-upvoted question. The title is a very short description of exactly what the code does. \$\endgroup\$ – Fund Monica's Lawsuit Jun 24 '15 at 5:23
  • \$\begingroup\$ Okay, maybe I was wrong to post this here. This doesn't even seem like the right place to ask this, since it's less about the code and more about how I've documented it. \$\endgroup\$ – user76420 Jun 24 '15 at 5:26
  • \$\begingroup\$ This question looks fine to me. \$\endgroup\$ – 200_success Jun 24 '15 at 5:29
0
\$\begingroup\$

The docs looks GOOD to me, it explains and provides an example of how to use it, so it will be quite easy to anyone use it and achieve what is needed.

You explain each main blocks with a comment, and avoid overcommenting, what is good, so, commenting in my opinion is really well done.

The only issues I see here are not related with doc, but with the code format and the fact you don't write any brace on one line block loops.

  • Code format: When coding, try to attach to a format, for example PSR-2, follow a standard will help you to share the code and make sure that anybody has the same way to follow it. You can read more on it in https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md.
  • Writing Braces: Your loops structures lack braces in one line blocks of code. Whilst this (of course) will work, may lead to horrible situations later, if you, for example are in a hurry and write a second line without realizing. The second line will be always applied out of the if or just one if it's a for. Is a good practice ALWAYS open and close your loops, even if they are a one-line loop blocks.
\$\endgroup\$
  • \$\begingroup\$ Okay, no offence, but my coding style is pretty personal to me, and I guard it quite stubbornly. Every "standard" that people try putting forth as a recommendation looks foreign and forced to me, and (I'm not gonna sugarcoat this), my blood boils any time I see something like "use 4 spaces for indenting, not tabs". Because people who indent with spaces and encourage others to do so are the ones I'm tempted to punch in the face... \$\endgroup\$ – user76420 Jun 25 '15 at 11:01
  • \$\begingroup\$ Now, regarding the braces, I find it superfluous if there's only one line of code that needs to be bracketed. To me, it just looks neater: and I generally isolate them from surrounding lines of code (with proper hard-tab indentation) to reduce the risk of blurring the lines. I understand you're trying to be helpful, but of all things that do and don't irritate me, coding style is one that manages to hit me the worst. But... yeah, thanks. \$\endgroup\$ – user76420 Jun 25 '15 at 11:02
  • \$\begingroup\$ Anyway, sorry I don't sound more grateful that you've stopped to offer your help, but I only asked for my documentation to be reviewed, and anybody suggesting I change my coding style happens to touch on something I'm extremely opinionated about... As a guy once said, "standards are unicorns". If your code's readable, cleanly indented and not bloated with spaces, fine by me. \$\endgroup\$ – user76420 Jun 25 '15 at 11:05
  • \$\begingroup\$ I'm marking this as the correct answer because you gave me a thorough overview of how I documented the method, which is what I was looking for. Thanks. \$\endgroup\$ – user76420 Jun 25 '15 at 11:10
  • \$\begingroup\$ Hahahaha, no offence at all, XD. I understand that it's a very personal matter, and as it's the first time we meet I didn't know if you had taken that into account or not, ;D. The braces is only a question of avoiding future mistakes, and just (again) pointing something just in case. As your docs where good and I saw that, I pointed that just FYI (in case you didn't know/realize of it, which is not the case, XD). \$\endgroup\$ – Chococroc Jun 25 '15 at 14:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy