Set

Array management, if done right, can be a very powerful and useful tool for building smarter, more optimized code. CakePHP offers a very useful set of static utilities in the Set class that allow you to do just that.

CakePHP’s Set class can be called from any model or controller in the same way Inflector is called. Example: Set::combine().

Set-compatible Path syntax

The Path syntax is used by (for example) sort, and is used to define a path.

Usage example (using Set::sort()):

$a = array(
    0 => array('Person' => array('name' => 'Jeff')),
    1 => array('Shirt' => array('color' => 'black'))
);
$result = Set::sort($a, '{n}.Person.name', 'asc');
/* $result now looks like:
    Array
    (
        [0] => Array
            (
                [Shirt] => Array
                    (
                        [color] => black
                    )
            )
        [1] => Array
            (
                [Person] => Array
                    (
                        [name] => Jeff
                    )
            )
    )
*/

As you can see in the example above, some things are wrapped in {}’s, others not. In the table below, you can see which options are available.

Expression

Definition

{n}

Represents a numeric key

{s}

Represents a string

Foo

Any string (without enclosing brackets) is treated like a string literal.

{[a-z]+}

Any string enclosed in brackets (besides {n} and {s}) is interpreted as a regular expression.

This section needs to be expanded.

insert

array Set::insert ($list, $path, $data = null)

Inserts $data into an array as defined by $path.

$a = array(
    'pages' => array('name' => 'page')
);
$result = Set::insert($a, 'files', array('name' => 'files'));
/* $result now looks like:
    Array
    (
        [pages] => Array
            (
                [name] => page
            )
        [files] => Array
            (
                [name] => files
            )
    )
*/

$a = array(
    'pages' => array('name' => 'page')
);
$result = Set::insert($a, 'pages.name', array());
/* $result now looks like:
    Array
    (
        [pages] => Array
            (
                [name] => Array
                    (
                    )
            )
    )
*/

$a = array(
    'pages' => array(
        0 => array('name' => 'main'),
        1 => array('name' => 'about')
    )
);
$result = Set::insert($a, 'pages.1.vars', array('title' => 'page title'));
/* $result now looks like:
    Array
    (
        [pages] => Array
            (
                [0] => Array
                    (
                        [name] => main
                    )
                [1] => Array
                    (
                        [name] => about
                        [vars] => Array
                            (
                                [title] => page title
                            )
                    )
            )
    )
*/

sort

array Set::sort ($data, $path, $dir)

Sorts an array by any value, determined by a Set-compatible path.

$a = array(
    0 => array('Person' => array('name' => 'Jeff')),
    1 => array('Shirt' => array('color' => 'black'))
);
$result = Set::sort($a, '{n}.Person.name', 'asc');
/* $result now looks like:
    Array
    (
        [0] => Array
            (
                [Shirt] => Array
                    (
                        [color] => black
                    )
            )
        [1] => Array
            (
                [Person] => Array
                    (
                        [name] => Jeff
                    )
            )
    )
*/

$result = Set::sort($a, '{n}.Shirt', 'asc');
/* $result now looks like:
    Array
    (
        [0] => Array
            (
                [Person] => Array
                    (
                        [name] => Jeff
                    )
            )
        [1] => Array
            (
                [Shirt] => Array
                    (
                        [color] => black
                    )
            )
    )
*/

$result = Set::sort($a, '{n}', 'desc');
/* $result now looks like:
    Array
    (
        [0] => Array
            (
                [Shirt] => Array
                    (
                        [color] => black
                    )
            )
        [1] => Array
            (
                [Person] => Array
                    (
                        [name] => Jeff
                    )
            )
    )
*/

$a = array(
    array(7,6,4),
    array(3,4,5),
    array(3,2,1),
);

$result = Set::sort($a, '{n}.{n}', 'asc');
/* $result now looks like:
    Array
    (
        [0] => Array
            (
                [0] => 3
                [1] => 2
                [2] => 1
            )
        [1] => Array
            (
                [0] => 3
                [1] => 4
                [2] => 5
            )
        [2] => Array
            (
                [0] => 7
                [1] => 6
                [2] => 4
            )
    )
*/

reverse

array Set::reverse ($object)

Set::reverse is basically the opposite of Set::map. It converts an object into an array. If $object is not an object, reverse will simply return $object.

$result = Set::reverse(null);
// Null
$result = Set::reverse(false);
// false
$a = array(
    'Post' => array('id'=> 1, 'title' => 'First Post'),
    'Comment' => array(
        array('id'=> 1, 'title' => 'First Comment'),
        array('id'=> 2, 'title' => 'Second Comment')
    ),
    'Tag' => array(
        array('id'=> 1, 'title' => 'First Tag'),
        array('id'=> 2, 'title' => 'Second Tag')
    ),
);
$map = Set::map($a); // Turn $a into a class object
/* $map now looks like:
    stdClass Object
    (
        [_name_] => Post
        [id] => 1
        [title] => First Post
        [Comment] => Array
            (
                [0] => stdClass Object
                    (
                        [id] => 1
                        [title] => First Comment
                    )
                [1] => stdClass Object
                    (
                        [id] => 2
                        [title] => Second Comment
                    )
            )
        [Tag] => Array
            (
                [0] => stdClass Object
                    (
                        [id] => 1
                        [title] => First Tag
                    )
                [1] => stdClass Object
                    (
                        [id] => 2
                        [title] => Second Tag
                    )
            )
    )
*/

$result = Set::reverse($map);
/* $result now looks like:
    Array
    (
        [Post] => Array
            (
                [id] => 1
                [title] => First Post
                [Comment] => Array
                    (
                        [0] => Array
                            (
                                [id] => 1
                                [title] => First Comment
                            )
                        [1] => Array
                            (
                                [id] => 2
                                [title] => Second Comment
                            )
                    )
                [Tag] => Array
                    (
                        [0] => Array
                            (
                                [id] => 1
                                [title] => First Tag
                            )
                        [1] => Array
                            (
                                [id] => 2
                                [title] => Second Tag
                            )
                    )
            )
    )
*/

$result = Set::reverse($a['Post']); // Just return the array
/* $result now looks like:
    Array
    (
        [id] => 1
        [title] => First Post
    )
*/

combine

array Set::combine ($data, $path1 = null, $path2 = null, $groupPath = null)

Creates an associative array using a $path1 as the path to build its keys, and optionally $path2 as path to get the values. If $path2 is not specified, all values will be initialized to null (useful for Set::merge). You can optionally group the values by what is obtained when following the path specified in $groupPath.

$result = Set::combine(array(), '{n}.User.id', '{n}.User.Data');
// $result == array();

$result = Set::combine('', '{n}.User.id', '{n}.User.Data');
// $result == array();

$a = array(
    array(
        'User' => array(
            'id' => 2,
            'group_id' => 1,
            'Data' => array(
                'user' => 'mariano.iglesias',
                'name' => 'Mariano Iglesias'
            )
        )
    ),
    array(
        'User' => array(
            'id' => 14,
            'group_id' => 2,
            'Data' => array(
                'user' => 'phpnut',
                'name' => 'Larry E. Masters'
            )
        )
    ),
    array(
        'User' => array(
            'id' => 25,
            'group_id' => 1,
            'Data' => array(
                'user' => 'gwoo',
                'name' => 'The Gwoo'
            )
        )
    )
);
$result = Set::combine($a, '{n}.User.id');
/* $result now looks like:
    Array
    (
        [2] =>
        [14] =>
        [25] =>
    )
*/

$result = Set::combine($a, '{n}.User.id', '{n}.User.non-existant');
/* $result now looks like:
    Array
    (
        [2] =>
        [14] =>
        [25] =>
    )
*/

$result = Set::combine($a, '{n}.User.id', '{n}.User.Data');
/* $result now looks like:
    Array
    (
        [2] => Array
            (
                [user] => mariano.iglesias
                [name] => Mariano Iglesias
            )
        [14] => Array
            (
                [user] => phpnut
                [name] => Larry E. Masters
            )
        [25] => Array
            (
                [user] => gwoo
                [name] => The Gwoo
            )
    )
*/

$result = Set::combine($a, '{n}.User.id', '{n}.User.Data.name');
/* $result now looks like:
    Array
    (
        [2] => Mariano Iglesias
        [14] => Larry E. Masters
        [25] => The Gwoo
    )
*/

$result = Set::combine($a, '{n}.User.id', '{n}.User.Data', '{n}.User.group_id');
/* $result now looks like:
    Array
    (
        [1] => Array
            (
                [2] => Array
                    (
                        [user] => mariano.iglesias
                        [name] => Mariano Iglesias
                    )
                [25] => Array
                    (
                        [user] => gwoo
                        [name] => The Gwoo
                    )
            )
        [2] => Array
            (
                [14] => Array
                    (
                        [user] => phpnut
                        [name] => Larry E. Masters
                    )
            )
    )
*/

$result = Set::combine($a, '{n}.User.id', '{n}.User.Data.name', '{n}.User.group_id');
/* $result now looks like:
    Array
    (
        [1] => Array
            (
                [2] => Mariano Iglesias
                [25] => The Gwoo
            )
        [2] => Array
            (
                [14] => Larry E. Masters
            )
    )
*/

$result = Set::combine($a, '{n}.User.id', array('{0}: {1}', '{n}.User.Data.user', '{n}.User.Data.name'), '{n}.User.group_id');
/* $result now looks like:
    Array
    (
        [1] => Array
            (
                [2] => mariano.iglesias: Mariano Iglesias
                [25] => gwoo: The Gwoo
            )
        [2] => Array
            (
                [14] => phpnut: Larry E. Masters
            )
    )
*/

$result = Set::combine($a, array('{0}: {1}', '{n}.User.Data.user', '{n}.User.Data.name'), '{n}.User.id');
/* $result now looks like:
    Array
    (
        [mariano.iglesias: Mariano Iglesias] => 2
        [phpnut: Larry E. Masters] => 14
        [gwoo: The Gwoo] => 25
    )
*/

$result = Set::combine($a, array('{1}: {0}', '{n}.User.Data.user', '{n}.User.Data.name'), '{n}.User.id');
/* $result now looks like:
    Array
    (
        [Mariano Iglesias: mariano.iglesias] => 2
        [Larry E. Masters: phpnut] => 14
        [The Gwoo: gwoo] => 25
    )
*/

$result = Set::combine($a, array('%1$s: %2$d', '{n}.User.Data.user', '{n}.User.id'), '{n}.User.Data.name');

/* $result now looks like:
    Array
    (
        [mariano.iglesias: 2] => Mariano Iglesias
        [phpnut: 14] => Larry E. Masters
        [gwoo: 25] => The Gwoo
    )
*/

$result = Set::combine($a, array('%2$d: %1$s', '{n}.User.Data.user', '{n}.User.id'), '{n}.User.Data.name');
/* $result now looks like:
    Array
    (
        [2: mariano.iglesias] => Mariano Iglesias
        [14: phpnut] => Larry E. Masters
        [25: gwoo] => The Gwoo
    )
*/

normalize

array Set::normalize ($list, $assoc = true, $sep = ',', $trim = true)

Normalizes a string or array list.

$a = array('Tree', 'CounterCache',
        'Upload' => array(
            'folder' => 'products',
            'fields' => array('image_1_id', 'image_2_id', 'image_3_id', 'image_4_id', 'image_5_id')));
$b =  array('Cacheable' => array('enabled' => false),
        'Limit',
        'Bindable',
        'Validator',
        'Transactional');
$result = Set::normalize($a);
/* $result now looks like:
    Array
    (
        [Tree] =>
        [CounterCache] =>
        [Upload] => Array
            (
                [folder] => products
                [fields] => Array
                    (
                        [0] => image_1_id
                        [1] => image_2_id
                        [2] => image_3_id
                        [3] => image_4_id
                        [4] => image_5_id
                    )
            )
    )
*/
$result = Set::normalize($b);
/* $result now looks like:
    Array
    (
        [Cacheable] => Array
            (
                [enabled] =>
            )

        [Limit] =>
        [Bindable] =>
        [Validator] =>
        [Transactional] =>
    )
*/
$result = Set::merge($a, $b); // Now merge the two and normalize
/* $result now looks like:
    Array
    (
        [0] => Tree
        [1] => CounterCache
        [Upload] => Array
            (
                [folder] => products
                [fields] => Array
                    (
                        [0] => image_1_id
                        [1] => image_2_id
                        [2] => image_3_id
                        [3] => image_4_id
                        [4] => image_5_id
                    )

            )
        [Cacheable] => Array
            (
                [enabled] =>
            )
        [2] => Limit
        [3] => Bindable
        [4] => Validator
        [5] => Transactional
    )
*/
$result = Set::normalize(Set::merge($a, $b));
/* $result now looks like:
    Array
    (
        [Tree] =>
        [CounterCache] =>
        [Upload] => Array
            (
                [folder] => products
                [fields] => Array
                    (
                        [0] => image_1_id
                        [1] => image_2_id
                        [2] => image_3_id
                        [3] => image_4_id
                        [4] => image_5_id
                    )

            )
        [Cacheable] => Array
            (
                [enabled] =>
            )
        [Limit] =>
        [Bindable] =>
        [Validator] =>
        [Transactional] =>
    )
*/

countDim

integer Set::countDim ($array = null, $all = false, $count = 0)

Counts the dimensions of an array. If $all is set to false (which is the default) it will only consider the dimension of the first element in the array.

$data = array('one', '2', 'three');
$result = Set::countDim($data);
// $result == 1

$data = array('1' => '1.1', '2', '3');
$result = Set::countDim($data);
// $result == 1

$data = array('1' => array('1.1' => '1.1.1'), '2', '3' => array('3.1' => '3.1.1'));
$result = Set::countDim($data);
// $result == 2

$data = array('1' => '1.1', '2', '3' => array('3.1' => '3.1.1'));
$result = Set::countDim($data);
// $result == 1

$data = array('1' => '1.1', '2', '3' => array('3.1' => '3.1.1'));
$result = Set::countDim($data, true);
// $result == 2

$data = array('1' => array('1.1' => '1.1.1'), '2', '3' => array('3.1' => array('3.1.1' => '3.1.1.1')));
$result = Set::countDim($data);
// $result == 2

$data = array('1' => array('1.1' => '1.1.1'), '2', '3' => array('3.1' => array('3.1.1' => '3.1.1.1')));
$result = Set::countDim($data, true);
// $result == 3

$data = array('1' => array('1.1' => '1.1.1'), array('2' => array('2.1' => array('2.1.1' => '2.1.1.1'))), '3' => array('3.1' => array('3.1.1' => '3.1.1.1')));
$result = Set::countDim($data, true);
// $result == 4

$data = array('1' => array('1.1' => '1.1.1'), array('2' => array('2.1' => array('2.1.1' => array('2.1.1.1')))), '3' => array('3.1' => array('3.1.1' => '3.1.1.1')));
$result = Set::countDim($data, true);
// $result == 5

$data = array('1' => array('1.1' => '1.1.1'), array('2' => array('2.1' => array('2.1.1' => array('2.1.1.1' => '2.1.1.1.1')))), '3' => array('3.1' => array('3.1.1' => '3.1.1.1')));
$result = Set::countDim($data, true);
// $result == 5

$set = array('1' => array('1.1' => '1.1.1'), array('2' => array('2.1' => array('2.1.1' => array('2.1.1.1' => '2.1.1.1.1')))), '3' => array('3.1' => array('3.1.1' => '3.1.1.1')));
$result = Set::countDim($set, false, 0);
// $result == 2

$result = Set::countDim($set, true);
// $result == 5

isEqual

boolean Set::isEqual ($val1, $val2 = null)

Determines if two Sets or arrays are equal.

$result = Set::isEqual(array(1), array(1,1));
// False
$result = Set::isEqual(array(1), array(1));
// True

diff

array Set::diff ($val1, $val2 = null)

Computes the difference between a Set and an array, two Sets, or two arrays

$a = array(
    0 => array('name' => 'main'),
    1 => array('name' => 'about')
);
$b = array(
    0 => array('name' => 'main'),
    1 => array('name' => 'about'),
    2 => array('name' => 'contact')
);

$result = Set::diff($a, $b);
/* $result now looks like:
    Array
    (
        [2] => Array
            (
                [name] => contact
            )
    )
*/
$result = Set::diff($a, array());
/* $result now looks like:
    Array
    (
        [0] => Array
            (
                [name] => main
            )
        [1] => Array
            (
                [name] => about
            )
    )
*/
$result = Set::diff(array(), $b);
/* $result now looks like:
    Array
    (
        [0] => Array
            (
                [name] => main
            )
        [1] => Array
            (
                [name] => about
            )
        [2] => Array
            (
                [name] => contact
            )
    )
*/

$b = array(
    0 => array('name' => 'me'),
    1 => array('name' => 'about')
);

$result = Set::diff($a, $b);
/* $result now looks like:
    Array
    (
        [0] => Array
            (
                [name] => main
            )
    )
*/

check

boolean/array Set::check ($data, $path = null)

Checks if a particular path is set in an array. If $path is empty, $data will be returned instead of a boolean value.

$set = array(
    'My Index 1' => array('First' => 'The first item')
);
$result = Set::check($set, 'My Index 1.First');
// $result == True
$result = Set::check($set, 'My Index 1');
// $result == True
$result = Set::check($set, array());
// $result == array('My Index 1' => array('First' => 'The first item'))
$set = array(
    'My Index 1' => array('First' =>
        array('Second' =>
            array('Third' =>
                array('Fourth' => 'Heavy. Nesting.'))))
);
$result = Set::check($set, 'My Index 1.First.Second');
// $result == True
$result = Set::check($set, 'My Index 1.First.Second.Third');
// $result == True
$result = Set::check($set, 'My Index 1.First.Second.Third.Fourth');
// $result == True
$result = Set::check($set, 'My Index 1.First.Seconds.Third.Fourth');
// $result == False

remove

array Set::remove ($list, $path = null)

Removes an element from a Set or array as defined by $path.

$a = array(
    'pages'     => array('name' => 'page'),
    'files'     => array('name' => 'files')
);

$result = Set::remove($a, 'files');
/* $result now looks like:
    Array
    (
        [pages] => Array
            (
                [name] => page
            )

    )
*/

classicExtract

array Set::classicExtract ($data, $path = null)

Gets a value from an array or object that is contained in a given path using an array path syntax, i.e.:

  • “{n}.Person.{[a-z]+}” - Where “{n}” represents a numeric key, “Person” represents a string literal

  • “{[a-z]+}” (i.e. any string literal enclosed in brackets besides {n} and {s}) is interpreted as a regular expression.

Example 1

$a = array(
    array('Article' => array('id' => 1, 'title' => 'Article 1')),
    array('Article' => array('id' => 2, 'title' => 'Article 2')),
    array('Article' => array('id' => 3, 'title' => 'Article 3')));
$result = Set::classicExtract($a, '{n}.Article.id');
/* $result now looks like:
    Array
    (
        [0] => 1
        [1] => 2
        [2] => 3
    )
*/
$result = Set::classicExtract($a, '{n}.Article.title');
/* $result now looks like:
    Array
    (
        [0] => Article 1
        [1] => Article 2
        [2] => Article 3
    )
*/
$result = Set::classicExtract($a, '1.Article.title');
// $result == "Article 2"

$result = Set::classicExtract($a, '3.Article.title');
// $result == null

Example 2

$a = array(
    0 => array('pages' => array('name' => 'page')),
    1 => array('fruites'=> array('name' => 'fruit')),
    'test' => array(array('name' => 'jippi')),
    'dot.test' => array(array('name' => 'jippi'))
);

$result = Set::classicExtract($a, '{n}.{s}.name');
/* $result now looks like:
Array
    (
        [0] => Array
            (
                [0] => page
            )
        [1] => Array
            (
                [0] => fruit
            )
    )
*/
$result = Set::classicExtract($a, '{s}.{n}.name');
/* $result now looks like:
    Array
    (
        [0] => Array
            (
                [0] => jippi
            )
        [1] => Array
            (
                [0] => jippi
            )
    )
*/
$result = Set::classicExtract($a,'{\w+}.{\w+}.name');
/* $result now looks like:
    Array
    (
        [0] => Array
            (
                [pages] => page
            )
        [1] => Array
            (
                [fruites] => fruit
            )
        [test] => Array
            (
                [0] => jippi
            )
        [dot.test] => Array
            (
                [0] => jippi
            )
    )
*/
$result = Set::classicExtract($a,'{\d+}.{\w+}.name');
/* $result now looks like:
    Array
    (
        [0] => Array
            (
                [pages] => page
            )
        [1] => Array
            (
                [fruites] => fruit
            )
    )
*/
$result = Set::classicExtract($a,'{n}.{\w+}.name');
/* $result now looks like:
    Array
    (
        [0] => Array
            (
                [pages] => page
            )
        [1] => Array
            (
                [fruites] => fruit
            )
    )
*/
$result = Set::classicExtract($a,'{s}.{\d+}.name');
/* $result now looks like:
    Array
    (
        [0] => Array
            (
                [0] => jippi
            )
        [1] => Array
            (
                [0] => jippi
            )
    )
*/
$result = Set::classicExtract($a,'{s}');
/* $result now looks like:
    Array
    (

        [0] => Array
            (
                [0] => Array
                    (
                        [name] => jippi
                    )
            )
        [1] => Array
            (
                [0] => Array
                    (
                        [name] => jippi
                    )
            )
    )
*/
$result = Set::classicExtract($a,'{[a-z]}');
/* $result now looks like:
    Array
    (
        [test] => Array
            (
                [0] => Array
                    (
                        [name] => jippi
                    )
            )

        [dot.test] => Array
            (
                [0] => Array
                    (
                        [name] => jippi
                    )
            )
    )
*/
$result = Set::classicExtract($a, '{dot\.test}.{n}');
/* $result now looks like:
    Array
    (
        [dot.test] => Array
            (
                [0] => Array
                    (
                        [name] => jippi
                    )
            )
    )
*/

matches

boolean Set::matches ($conditions, $data=array(), $i = null, $length=null)

Set::matches can be used to see if a single item or a given xpath match certain conditions.

$a = array(
    array('Article' => array('id' => 1, 'title' => 'Article 1')),
    array('Article' => array('id' => 2, 'title' => 'Article 2')),
    array('Article' => array('id' => 3, 'title' => 'Article 3')));
$res=Set::matches(array('id>2'), $a[1]['Article']);
// returns false
$res=Set::matches(array('id>=2'), $a[1]['Article']);
// returns true
$res=Set::matches(array('id>=3'), $a[1]['Article']);
// returns false
$res=Set::matches(array('id<=2'), $a[1]['Article']);
// returns true
$res=Set::matches(array('id<2'), $a[1]['Article']);
// returns false
$res=Set::matches(array('id>1'), $a[1]['Article']);
// returns true
$res=Set::matches(array('id>1', 'id<3', 'id!=0'), $a[1]['Article']);
// returns true
$res=Set::matches(array('3'), null, 3);
// returns true
$res=Set::matches(array('5'), null, 5);
// returns true
$res=Set::matches(array('id'), $a[1]['Article']);
// returns true
$res=Set::matches(array('id', 'title'), $a[1]['Article']);
// returns true
$res=Set::matches(array('non-existant'), $a[1]['Article']);
// returns false
$res=Set::matches('/Article[id=2]', $a);
// returns true
$res=Set::matches('/Article[id=4]', $a);
// returns false
$res=Set::matches(array(), $a);
// returns true

extract

array Set::extract ($path, $data=null, $options=array())

Set::extract uses basic XPath 2.0 syntax to return subsets of your data from a find or a find all. This function allows you to retrieve your data quickly without having to loop through multi dimentional arrays or traverse through tree structures.

If $path is an array or $data is empty it the call is delegated to Set::classicExtract.

// Common Usage:
$users = $this->User->find("all");
$results = Set::extract('/User/id', $users);
// results returns:
// array(1,2,3,4,5,...);

Currently implemented selectors:

Selector

Note

/User/id

Similar to the classic {n}.User.id

/User[2]/name

Selects the name of the second User

/User[id<2]

Selects all Users with an id < 2

/User[id>2][<5]

Selects all Users with an id > 2 but < 5

/Post/Comment[author_name=john]/../name

Selects the name of all Posts that have at least one Comment written by john

/Posts[title]

Selects all Posts that have a ‘title’ key

/Comment/.[1]

Selects the contents of the first comment

/Comment/.[:last]

Selects the last comment

/Comment/.[:first]

Selects the first comment

/Comment[text=/cakephp/i]

Selects all comments that have a text matching the regex /cakephp/i

/Comment/@*

Selects the key names of all comments

Currently only absolute paths starting with a single ‘/’ are supported. Please report any bugs as you find them. Suggestions for additional features are welcome.

To learn more about Set::extract() refer to function testExtract() in /cake/tests/cases/libs/set.test.php.

format

array Set::format ($data, $format, $keys)

Returns a series of values extracted from an array, formatted in a format string.

$data = array(
    array('Person' => array('first_name' => 'Nate', 'last_name' => 'Abele', 'city' => 'Boston', 'state' => 'MA', 'something' => '42')),
    array('Person' => array('first_name' => 'Larry', 'last_name' => 'Masters', 'city' => 'Boondock', 'state' => 'TN', 'something' => '{0}')),
    array('Person' => array('first_name' => 'Garrett', 'last_name' => 'Woodworth', 'city' => 'Venice Beach', 'state' => 'CA', 'something' => '{1}')));

$res = Set::format($data, '{1}, {0}', array('{n}.Person.first_name', '{n}.Person.last_name'));
/*
Array
(
    [0] => Abele, Nate
    [1] => Masters, Larry
    [2] => Woodworth, Garrett
)
*/

$res = Set::format($data, '{0}, {1}', array('{n}.Person.city', '{n}.Person.state'));
/*
Array
(
    [0] => Boston, MA
    [1] => Boondock, TN
    [2] => Venice Beach, CA
)
*/
$res = Set::format($data, '{{0}, {1}}', array('{n}.Person.city', '{n}.Person.state'));
/*
Array
(
    [0] => {Boston, MA}
    [1] => {Boondock, TN}
    [2] => {Venice Beach, CA}
)
*/
$res = Set::format($data, '{%2$d, %1$s}', array('{n}.Person.something', '{n}.Person.something'));
/*
Array
(
    [0] => {42, 42}
    [1] => {0, {0}}
    [2] => {0, {1}}
)
*/
$res = Set::format($data, '%2$d, %1$s', array('{n}.Person.first_name', '{n}.Person.something'));
/*
Array
(
    [0] => 42, Nate
    [1] => 0, Larry
    [2] => 0, Garrett
)
*/
$res = Set::format($data, '%1$s, %2$d', array('{n}.Person.first_name', '{n}.Person.something'));
/*
Array
(
    [0] => Nate, 42
    [1] => Larry, 0
    [2] => Garrett, 0
)
*/

enum

string Set::enum ($select, $list=null)

The enum method works well when using html select elements. It returns a value from an array list if the key exists.

If a comma separated $list is passed arrays are numeric with the key of the first being 0 $list = ‘no, yes’ would translate to $list = array(0 => ‘no’, 1 => ‘yes’);

If an array is used, keys can be strings example: array(‘no’ => 0, ‘yes’ => 1);

$list defaults to 0 = no 1 = yes if param is not passed

$res = Set::enum(1, 'one, two');
// $res is 'two'

$res = Set::enum('no', array('no' => 0, 'yes' => 1));
// $res is 0

$res = Set::enum('first', array('first' => 'one', 'second' => 'two'));
// $res is 'one'

numeric

boolean Set::numeric ($array=null)

Checks to see if all the values in the array are numeric

$data = array('one');
$res = Set::numeric(array_keys($data));

// $res is true

$data = array(1 => 'one');
$res = Set::numeric($data);

// $res is false

$data = array('one');
$res = Set::numeric($data);

// $res is false

$data = array('one' => 'two');
$res = Set::numeric($data);

// $res is false

$data = array('one' => 1);
$res = Set::numeric($data);

// $res is true

$data = array(0);
$res = Set::numeric($data);

// $res is true

$data = array('one', 'two', 'three', 'four', 'five');
$res = Set::numeric(array_keys($data));

// $res is true

$data = array(1 => 'one', 2 => 'two', 3 => 'three', 4 => 'four', 5 => 'five');
$res = Set::numeric(array_keys($data));

// $res is true

$data = array('1' => 'one', 2 => 'two', 3 => 'three', 4 => 'four', 5 => 'five');
$res = Set::numeric(array_keys($data));

// $res is true

$data = array('one', 2 => 'two', 3 => 'three', 4 => 'four', 'a' => 'five');
$res = Set::numeric(array_keys($data));

// $res is false

map

object Set::map ($class = 'stdClass', $tmp = 'stdClass')

This method Maps the contents of the Set object to an object hierarchy while maintaining numeric keys as arrays of objects.

Basically, the map function turns array items into initialized class objects. By default it turns an array into a stdClass Object, however you can map values into any type of class. Example: Set::map($array_of_values, ‘nameOfYourClass’);

$data = array(
    array(
        "IndexedPage" => array(
            "id" => 1,
            "url" => 'http://blah.com/',
            'hash' => '68a9f053b19526d08e36c6a9ad150737933816a5',
            'get_vars' => '',
            'redirect' => '',
            'created' => "1195055503",
            'updated' => "1195055503",
        )
    ),
    array(
        "IndexedPage" => array(
            "id" => 2,
            "url" => 'http://blah.com/',
            'hash' => '68a9f053b19526d08e36c6a9ad150737933816a5',
            'get_vars' => '',
            'redirect' => '',
            'created' => "1195055503",
            'updated' => "1195055503",
        ),
    )
);
$mapped = Set::map($data);

/* $mapped now looks like:

    Array
    (
        [0] => stdClass Object
            (
                [_name_] => IndexedPage
                [id] => 1
                [url] => http://blah.com/
                [hash] => 68a9f053b19526d08e36c6a9ad150737933816a5
                [get_vars] =>
                [redirect] =>
                [created] => 1195055503
                [updated] => 1195055503
            )

        [1] => stdClass Object
            (
                [_name_] => IndexedPage
                [id] => 2
                [url] => http://blah.com/
                [hash] => 68a9f053b19526d08e36c6a9ad150737933816a5
                [get_vars] =>
                [redirect] =>
                [created] => 1195055503
                [updated] => 1195055503
            )

    )

*/

Using Set::map() with a custom class for second parameter:

class MyClass {
    function sayHi() {
        echo 'Hi!';
    }
}

$mapped = Set::map($data, 'MyClass');
//Now you can access all the properties as in the example above,
//but also you can call MyClass's methods
$mapped->[0]->sayHi();

pushDiff

array Set::pushDiff ($array1, $array2)

This function merges two arrays and pushes the differences in array2 to the bottom of the resultant array.

Example 1

$array1 = array('ModelOne' => array('id'=>1001, 'field_one'=>'a1.m1.f1', 'field_two'=>'a1.m1.f2'));
$array2 = array('ModelOne' => array('id'=>1003, 'field_one'=>'a3.m1.f1', 'field_two'=>'a3.m1.f2', 'field_three'=>'a3.m1.f3'));
$res = Set::pushDiff($array1, $array2);

/* $res now looks like:
    Array
    (
        [ModelOne] => Array
            (
                [id] => 1001
                [field_one] => a1.m1.f1
                [field_two] => a1.m1.f2
                [field_three] => a3.m1.f3
            )
    )
*/

Example 2

$array1 = array("a"=>"b", 1 => 20938, "c"=>"string");
$array2 = array("b"=>"b", 3 => 238, "c"=>"string", array("extra_field"));
$res = Set::pushDiff($array1, $array2);
/* $res now looks like:
    Array
    (
        [a] => b
        [1] => 20938
        [c] => string
        [b] => b
        [3] => 238
        [4] => Array
            (
                [0] => extra_field
            )
    )
*/

filter

array Set::filter ($var, $isArray=null)

Filters empty elements out of a route array, excluding ‘0’.

$res = Set::filter(array('0', false, true, 0, array('one thing', 'I can tell you', 'is you got to be', false)));

/* $res now looks like:
    Array (
        [0] => 0
        [2] => 1
        [3] => 0
        [4] => Array
            (
                [0] => one thing
                [1] => I can tell you
                [2] => is you got to be
                [3] =>
            )
    )
*/

merge

array Set::merge ($arr1, $arr2=null)

This function can be thought of as a hybrid between PHP’s array_merge and array_merge_recursive. The difference to the two is that if an array key contains another array then the function behaves recursive (unlike array_merge) but does not do if for keys containing strings (unlike array_merge_recursive). See the unit test for more information.

This function will work with an unlimited amount of arguments and typecasts non-array parameters into arrays.

$arry1 = array(
    array(
        'id' => '48c2570e-dfa8-4c32-a35e-0d71cbdd56cb',
        'name' => 'mysql raleigh-workshop-08 < 2008-09-05.sql ',
        'description' => 'Importing an sql dump'
    ),
    array(
        'id' => '48c257a8-cf7c-4af2-ac2f-114ecbdd56cb',
        'name' => 'pbpaste | grep -i Unpaid | pbcopy',
        'description' => 'Remove all lines that say "Unpaid".',
    )
);
$arry2 = 4;
$arry3 = array(0=>"test array", "cats"=>"dogs", "people" => 1267);
$arry4 = array("cats"=>"felines", "dog"=>"angry");
$res = Set::merge($arry1, $arry2, $arry3, $arry4);

/* $res now looks like:
Array
(
    [0] => Array
        (
            [id] => 48c2570e-dfa8-4c32-a35e-0d71cbdd56cb
            [name] => mysql raleigh-workshop-08 < 2008-09-05.sql
            [description] => Importing an sql dump
        )

    [1] => Array
        (
            [id] => 48c257a8-cf7c-4af2-ac2f-114ecbdd56cb
            [name] => pbpaste | grep -i Unpaid | pbcopy
            [description] => Remove all lines that say "Unpaid".
        )

    [2] => 4
    [3] => test array
    [cats] => felines
    [people] => 1267
    [dog] => angry
)
*/

contains

boolean Set::contains ($val1, $val2 = null)

Determines if one Set or array contains the exact keys and values of another.

$a = array(
    0 => array('name' => 'main'),
    1 => array('name' => 'about')
);
$b = array(
    0 => array('name' => 'main'),
    1 => array('name' => 'about'),
    2 => array('name' => 'contact'),
    'a' => 'b'
);

$result = Set::contains($a, $a);
// True
$result = Set::contains($a, $b);
// False
$result = Set::contains($b, $a);
// True