Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/topic.php on line 737
Форумы портала PHP.SU :: Функциональное разделение массивов

 PHP.SU

Программирование на PHP, MySQL и другие веб-технологии
PHP.SU Портал     На главную страницу форума Главная     Помощь Помощь     Поиск Поиск     Поиск Яндекс Поиск Яндекс     Вакансии  Пользователи Пользователи


 Страниц (1): [1]   

> Описание: Многозначная функция обратного вызова
EuGen Администратор
Отправлено: 04 Февраля, 2013 - 17:09:28
Post Id


Профессионал


Покинул форум
Сообщений всего: 9095
Дата рег-ции: Июнь 2007  
Откуда: Berlin


Помог: 707 раз(а)




Поскольку часто бывает нужно превосходить возможности array_filter, которая лишь фильтрует массив по некоторой функции, а писать каждый раз array_map - это не dry-подход, я использую простую функцию
PHP:
скопировать код в буфер обмена
  1. function array_split($rgData, $fnCallback, $bStoreGroup=false)
  2. {
  3.    if(!is_callable($fnCallback))
  4.    {
  5.       return null;
  6.    }
  7.    $rgResult = array();
  8.    foreach($rgData as $mValue)
  9.    {
  10.       $mFunctional = call_user_func($fnCallback, $mValue);
  11.       $sKey = $bStoreGroup?$mFunctional:serialize($mFunctional);
  12.       if(is_object($sKey))
  13.       {
  14.          try
  15.          {
  16.             $sKey=(string)$sKey;
  17.          }
  18.          catch(Exception $rException)
  19.          {
  20.             return null;
  21.          }
  22.       }
  23.       elseif(!is_scalar($sKey))
  24.       {
  25.          return null;
  26.       }
  27.       if(array_key_exists($sKey, $rgResult))
  28.       {
  29.          $rgResult[$sKey][]=$mValue;
  30.       }
  31.       else
  32.       {
  33.          $rgResult[$sKey] = array($mValue);
  34.       }
  35.    }
  36.    return $bStoreGroup?$rgResult:array_values($rgResult);
  37. }

Все, что она делает - применяет callback ко всем элементам массива и возвращает результирующий массив, в котором данные сгруппированы в соответствии со значениями этой функции. При этом есть возможность сохранения значения группирующей функции в ключах результирующего массива. Разумеется, это получится сделать, если эта функция возвращает скаляр, либо объект, который имеет метод строкового представления. В иных случаях при использовании опции возврата ключей эта функция даст null.
Пример:
PHP:
скопировать код в буфер обмена
  1. class Foo
  2. {
  3.    function calc($mParam)
  4.    {
  5.       return abs($mParam);
  6.    }
  7. }
  8. $rFoo = new Foo();
  9. $rgData= array("2", "-1", "1", "-2");
  10. //var_dump(array_split($rgData, array($rFoo, "calc"), true));


-----
Есть в мире две бесконечные вещи - это Вселенная и человеческая глупость. Но насчет первой .. я не уверен.
 
 Top
DeepVarvar Супермодератор
Отправлено: 04 Февраля, 2013 - 17:43:46
Post Id



Активный участник


Покинул форум
Сообщений всего: 10377
Дата рег-ции: Дек. 2008  
Откуда: Альфа Центавра


Помог: 353 раз(а)




EuGen пишет:
$mFunctional = $fnCallback($mValue);
Я честно забыл с какой версии доступно такое обращение именно к функциям?
 
 Top
OrmaJever
Отправлено: 04 Февраля, 2013 - 17:55:30
Post Id



Активный участник


Покинул форум
Сообщений всего: 7540
Дата рег-ции: Янв. 2010  
Откуда: Чернигов


Помог: 299 раз(а)




DeepVarvar пишет:
Я честно забыл с какой версии доступно такое обращение именно к функциям?

А?! 5.3 ?


-----
Если вы хотя бы 3-4 раза не решите всё выкинуть и начать заново - вы явно что-то делаете не так.
 
 Top
esterio
Отправлено: 04 Февраля, 2013 - 17:56:14
Post Id



Активный участник


Покинул форум
Сообщений всего: 5025
Дата рег-ции: Нояб. 2012  
Откуда: Украина, Львов


Помог: 127 раз(а)




DeepVarvar
Кажется такое и в 4-ой версии доступно было. Только интересует такое - такой ж подход нельзя применит к обьектам? тоесть мб лучше call_user_func?
 
 Top
EuGen Администратор
Отправлено: 04 Февраля, 2013 - 18:00:15
Post Id


Профессионал


Покинул форум
Сообщений всего: 9095
Дата рег-ции: Июнь 2007  
Откуда: Berlin


Помог: 707 раз(а)




Еще с php 4. По-хорошему, нужно еще делать проверку is_callable и возвращать null, если была неудача.
И - да, код можно улучшить с помощью call_user_func. Хотя у меня есть вариант рекурсивного вызова, когда группировка ведется по нескольким значениям - с использованием такого подхода. Позже предоставлю и его.
upd. "рекурсивный" вариант оказался неактуален, поскольку применяется к двумерным массивам и может быть заменен соответствующим callback-вызовом для этой функции.


-----
Есть в мире две бесконечные вещи - это Вселенная и человеческая глупость. Но насчет первой .. я не уверен.
 
 Top
Страниц (1): [1]
Сейчас эту тему просматривают: 0 (гостей: 0, зарегистрированных: 0)
« Пользовательские функции »


Все гости форума могут просматривать этот раздел.
Только зарегистрированные пользователи могут создавать новые темы в этом разделе.
Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.
 



Powered by PHP  Powered By MySQL  Powered by Nginx  Valid CSS  RSS

 
Powered by ExBB FM 1.0 RC1. InvisionExBB