An alternative way to create arrays

Published on and tagged with cakephp  feature

As I use more and more mock objects when testing I often have to fake the results of some findAll calls. That means I have to create array structures as shown in the following example:

$expectedPosts = array(array('Post' => array('id' => 3, 'title' => 'a title', 'content' => 'some content')), 
			               array('Post' => array('id' => 4, 'title' => 'another title', 'content' => 'some other content')));

The core class Set provides an alternative way to create arrays using a dot notation. The example from above can be rewritten as:

$expectedPosts = array();
$expectedPosts = Set::insert($expectedPosts, '0.Post.id', 3);
$expectedPosts = Set::insert($expectedPosts, '0.Post.title', 'a title');
$expectedPosts = Set::insert($expectedPosts, '0.Post.content', 'some content');
$expectedPosts = Set::insert($expectedPosts, '1.Post.id', 4);
$expectedPosts = Set::insert($expectedPosts, '1.Post.title', 'another title');
$expectedPosts = Set::insert($expectedPosts, '1.Post.content', 'some other content');

You can also mix those two approaches:

$expectedPosts = array();
$expectedPosts = Set::insert($expectedPosts, '0.Post', array('id' => 3, 'title' => 'a title', 'content' => 'some content'));
$expectedPosts = Set::insert($expectedPosts, '1.Post', array('id' => 4, 'title' => 'another title', 'content' => 'some other content'));

It is quite handy, especially if you have to create more complex array structures.

8 comments baked

  • Howard

    Brilliant & simple, but I’d never have noticed it without this post. Will beautify several horrible array constructions (findAll pivots and transformations not able to be done in the SQL) in a couple of my controller actions.

    Enjoy reading your blog thru google reader, keep them coming

  • Matt

    The mixed approach is great!

    Great way of improving code readability!

    I like all these insights very much.

    Thanks!

  • cakebaker

    @Howard, Matt: Thanks for your comments!

  • Lech

    For more readability I’d rather use a bit different array notation:

    $expectedPosts  = array(
            array(
                    'Post'  => array(
                            'id'        => 3,
                            'title'     => 'a title',
                            'content'   => 'some content'
                        )
                ),
            array(
                    'Post'  => array(
                            'id'        => 4,
                            'title'     => 'another title',
                            'content'   => 'some other content'
                        )
                ),
        );
    

    or using less space (worse case):

    $expectedPosts  = array(
            array('Post' => array(
                    'id'        => 3,
                    'title'     => 'a title',
                    'content'   => 'some content'
                )),
            array('Post' => array(
                    'id'        => 4,
                    'title'     => 'another title',
                    'content'   => 'some other content'
                )),
        );
    

    And don’t forget to avoid Set::insert in production because of performance ;)

  • Lech

    Doh, html pre tag was stripped, so indentation is missing.. Please view the source to see what I’ve ment in my previous comment :)

  • Brandon P

    Great post! If I’m not mistaken, Set class can also be instantiated:

    $expectedPosts = new Set();
    $expectedPosts->insert(‘0.Post.id’, 3);
    $expectedPosts->insert(‘0.Post.title’, ‘a title’);
    $expectedPosts->insert(‘0.Post.content’, ‘some content’);
    $expectedPosts->insert(‘1.Post.id’, 4);
    $expectedPosts->insert(‘1.Post.title’, ‘another title’);
    $expectedPosts->insert(‘1.Post.content’, ‘some other content’);
    $data = $expectedPosts->get();

  • cakebaker

    @Lech, Brandon: Thanks for your comments!

    @Lech: I fixed your comment by adding pre tags.

    Yes, that’s a possible way to structure arrays. I think it is a matter of preference whether you like it that way or not. Personally, I don’t like it. I prefer to create private methods to create the sub arrays.

    I think in most applications the impact of the described approach on the performance can be ignored ;-)

    @Brandon: Yes, that works. I wasn’t aware you could use it in this way, too.

  • Abhimanyu Grover

    Ah, what a shortcut… real cool !!

Bake a comment




(for code please use <code>...</code> [no escaping necessary])

© daniel hofstetter. Licensed under a Creative Commons License