Оказывается в недрах CakePHP давно живет класс Set, который активно используется в ядре и редко используется конечными пользователями. А между прочим зря.

Давайте-ка разберем типичную задачу. Предположим, мы получили список пользователей вот такого вида

$users = array
(
  0 => array
  (
    'User' => array
    (
      'id' => 1
      , 'name' => 'Вася'
    )   
  )
  , 1 => array
  (
    'User' => array
    (
      'id' => 2
      , 'name' => 'Петя'
    )
  )
  , 2 => array
  (
    'User' => array
    (
      'id' => 3
      , 'name' => 'Акакий'
    )
  )
);

и допустим нам нужно получить только их имена, в виде массива. Как это делается обычно? Ну вот так

$userNames = array();
foreach ($users as $user)
{
  $userNames[] = $user['User']['name'];
}

Казалось бы проще некуда. Но оказывается есть куда. Смотрите

$userNames = Set::extract($users, '{n}.User.name');

Не впечатляет? Тогда еще пример

$users = array
    (
      0 => array
      (
        'User' => array
        (
          'id' => 1
          , 'name' => 'Вася'
          , 'Item' => array
          (
            0 => array
            (
              'id' => 1
              , 'name' => 'Холодильник'
            )
            , 1 => array
            (
              'id' => 2
              , 'name' => 'Топор'
            )
          )
        )
      )
      , 1 => array
      (
        'User' => array
        (
          'id' => 2
          , 'name' => 'Петя'
          , 'Item' => array
          (
            0 => array
            (
              'id' => 3
              , 'name' => 'Машина'
            )
          )
        )
      )
      , 2 => array
      (
        'User' => array
        (
          'id' => 3
          , 'name' => 'Акакий'
          , 'Item' => array
          (
            0 => array
            (
              'id' => 4
              , 'name' => 'айфон'
            )
            , 1 => array
            (
              'id' => 5
              , 'name' => 'плэйер'
            )
            , 2 => array
            (
              'id' => 6
              , 'name' => 'мяч'
            )
          )
        )
      )
    );

Предположим нам нужно получить из этого массив вида ‘User.name’ => ‘User.items’. Вот традиционный подход.

$userItems = array();
foreach ($users as $user)
{
  foreach ($user['User']['Item'] as $item)
  {
    $userItems[$user['User']['name']][] = $item['name'];
  }
}

а вот с помощью Set

$userItems = Set::combine($users, '{n}.User.name', '{n}.User.Item.{n}.name');

результатом в обоих случаях будет

Array
(
  [Вася] => Array
    (
      [0] => Холодильник
      [1] => Топор
    )

  [Петя] => Array
    (
      [0] => Машина
    )

  [Акакий] => Array
    (
      [0] => айфон
      [1] => плэйер
      [2] => мяч
    )
)

На самом деле это лишь небольшая часть возможностей класса, в нем еще есть куча полезных методов. Set::merge — гибрид array_merge и array_merge_recursive (если элемент является массивом, то рекурсивная, если нет — то нет) Set::pushDiff — добавляет в конец первого массива разницу между ним и вторым массивом Set::extract — извлекает из массива информацию по XPath-селектору (‘/User/id’, например) Set::classicExtract — как и extract, только с классическими селекторами CakePHP (‘{n}.User.id’) Set::contains — есть ли в одном массиве ключи и значения из другого Set::diff — разница между двумя массивами Set::combine — создает из исходного массива ассоциированый с указанием ключей и значений (пример выше)