Skip to content

Instantly share code, notes, and snippets.

@johnkary
Last active August 29, 2015 14:16
Show Gist options
  • Save johnkary/a64363bac55c90a1ca97 to your computer and use it in GitHub Desktop.
Save johnkary/a64363bac55c90a1ca97 to your computer and use it in GitHub Desktop.
Example of using tuples instead of array key-value pairs
class BuildReport
{
private function getColumnHeaders()
{
// Why do you need array keys if this array is private details?
// It's never exposed outside this class so you have full control of its format
return [
['id' => 'first_name', 'label' => 'First Name'],
['id' => 'last_name', 'label' => 'Last Name'],
['id' => 'department', 'label' => 'Department'],
];
}
public function render($records)
{
foreach ($this->getColumnHeaders() as $header) {
$id = $header['id'];
$label = $header['label'];
// Do something with $id and label ...
}
}
}
class BuildReport
{
private function getColumnHeaders()
{
// If you need to change the data, the changes are confined to this class
return [
['first_name', 'First Name'],
['last_name', 'Last Name'],
['department', 'Department'],
];
}
public function render($records)
{
// PHP >= 5.5 -- This is the shortest thanks to this feature in 5.5 https://wiki.php.net/rfc/foreachlist
foreach ($this->getColumnHeaders() as list($id, $label)) {
// Do something with $id and label ...
}
// PHP < 5.5 -- This is slightly more code if you're running 5.4 or older
foreach ($this->getColumnHeaders() as $header) {
list($id, $label) = $header;
// Do something with $id and label ...
}
}
}
@johnkary
Copy link
Author

@darrencauthon My implementation in the gist above is PHP's shortest possible way to do what your Ruby example did. Using PHP, and in this use case, I don't see a benefit to using map.

For your reference, the equivalent PHP using map to your Ruby example is shown below. I think you'll agree it's much more difficult to visually parse. Watch it execute here. Code:

<?php

// Example 1 -- Unpacking the array to do work on it
array_map(function ($x) {
    $first_name = $x[0];
    $last_name = $x[1];

    // Do important work here with first_name and last_name...
    // But $first_name and $last_name are scoped to this function

    // See the second example for how we'd inject an anonymous function to operate with $first_name and $last_name
}, [
    ['John',  'Galt'],
    ['Howard', 'Roark'],
]);


// Example 2 -- Separation of input setup and behavior
$behavior = function ($first_name, $last_name) {
    var_dump('Doing hard work!', $first_name, $last_name);
};

array_map(function ($x) use ($behavior) {
    $first_name = $x[0];
    $last_name = $x[1];

    // $behavior is invoked using our unpacked arguments
    $behavior($first_name, $last_name);
}, [
    ['John',  'Galt'],
    ['Howard', 'Roark'],
]);

@darrencauthon
Copy link

Ah yikes, list away! ⛵ 😄

@archwisp
Copy link

This is what I was talking about on Twitter.

class BuildReport
{
    private function getColumnHeaders()
    {
        // If this method is private and consiming functions are expected
        // to know about its structure, why not do this and save the
        // consuming functions the work of local assignments.
        return [
            (object)['id' => 'first_name', 'label' => 'First Name'],
            (object)['id' => 'last_name',  'label' => 'Last Name'],
            (object)['id' => 'department', 'label' => 'Department'],
            ];
    }

    public function render($records)
    {
        foreach ($this->getColumnHeaders() as $header) {
            // Do something with $header->id and $header->label ...
        }
    }
}

@johnkary
Copy link
Author

@archwisp $header->id isn't bad but is equal in readability for me compared to $header['id']. I'm not sure on the performance impact from casting an array to an object, but doing so seems unnecessary if we're not gaining in readability inside our foreach.

@jrmadsen67
Copy link

Perhaps this is a bad example, but what do you do when you later on you need to add meta-data to each of these? ex: a class name to certain headers

It seems to me the weakness of a tuple is that by its very definition it is hard-coded to be a pair. I ccan see other examples where this could be desirable - key:values where you might actually like to enforce that pairing, but if that is not the case, you seem to lock yourself into a structure purely because you feel it "looks like nicer code"

Have I completely missed your point?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment