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
Форумы портала PHP.SU :: Версия для печати :: Как отфильтровать массив
Форумы портала PHP.SU » » Хранение данных, их вывод и обработка » Как отфильтровать массив

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

1. bkmz1984 - 18 Июля, 2016 - 15:50:37 - перейти к сообщению
Есть массив:

PHP:
скопировать код в буфер обмена
  1. $data[0] = array("data"=>"12.05.2016 11:00:20", "callid"=>"22", "name"=>"a");
  2. $data[1] = array("data"=>"12.05.2016 11:00:40", "callid"=>"22", "name"=>"b");
  3. $data[2] = array("data"=>"12.05.2016 11:01:02", "callid"=>"22", "name"=>"c");
  4. $data[3] = array("data"=>"12.05.2016 11:05:12", "callid"=>"33", "name"=>"d");


Как отфильтровать массив таким образом чтобы в рамках одного uid остались записи только с наименьшей датой и временем? т.е. 1-я запись и последняя
2. andrewkard - 18 Июля, 2016 - 16:07:21 - перейти к сообщению
3. bkmz1984 - 18 Июля, 2016 - 16:09:22 - перейти к сообщению
andrewkard пишет:
bkmz1984
http://php.net/manual/ru/function.usort.php

Отфильтровать, а не сортировать
4. andrewkard - 18 Июля, 2016 - 18:35:48 - перейти к сообщению
bkmz1984 пишет:
Отфильтровать, а не сортировать

http://php.net/manual/ru/functio...array-filter.php
5. bkmz1984 - 19 Июля, 2016 - 15:41:32 - перейти к сообщению
Товарищи кидать ссылки это не конструктивно

В общем я выношу на рассмотрение код.

PHP:
скопировать код в буфер обмена
  1. //  Массив в котором указываются все callid всех записей
  2. $all_callid = array();
  3. foreach ($data as $row) {
  4.     $all_callid[] = $row['callid'];
  5. }
  6.  
  7. // Функция для сортировки
  8. function sort_p($a, $b){
  9.     return strcmp($a["data"], $b["data"]);
  10. }
  11.  
  12. $data_end = array();
  13. // Перебираем все полученные индификаторы предварительно исключив повторяющиеся функцией array_unique()
  14. foreach (array_unique($all_callid) as $key => $value) {
  15.    
  16.     // Создаемм массивы сгруппированные по callid
  17.     $qw = array_filter($data, function ($row) use ($value) {
  18.         return ($row['callid'] == $value);
  19.     });
  20.    
  21.     // Сортируем массив по возрастанию даты используя функцию "sort_p"
  22.     uasort($qw, "sort_p");
  23.    
  24.     // Берем только первый элемент массива
  25.     $data_end[] = array_shift($qw);
  26.  
  27. }


Жду конструктивной критики
6. andrewkard - 20 Июля, 2016 - 13:34:44 - перейти к сообщению
Можно так:
PHP:
скопировать код в буфер обмена
  1.  
  2. $out = array();
  3. foreach ($data as $row){
  4.     $id = $row['callid'];
  5.     if (isset($out[$id])){
  6.         $out[$id] = min($out[$id],$row['data']);
  7.     } else {
  8.         $out[$id] = $row['data'];
  9.     }
  10. }
  11.  

(Добавление)
C array_filter кода будет побольше
(Добавление)
bkmz1984 пишет:
В общем я выношу на рассмотрение код.

В общем, для array_filter нужна предварительная обработка, то лучше будет в ней и вывести то что нужно.
Данные не из БД? Если из нее, то скорее всего можно сделать средствами СУБД
7. bkmz1984 - 21 Июля, 2016 - 09:51:07 - перейти к сообщению
andrewkard пишет:
В общем, для array_filter нужна предварительная обработка


Не совсем понял что имеется в виду?

andrewkard пишет:
Данные не из БД?


Из нее: MySQL.

andrewkard пишет:
Если из нее, то скорее всего можно сделать средствами СУБД


Это как-то с использованием подзапросов? ( OR NOT EXISTS(SELECT... или OR c.callid NOT IN (SELECT ...) ?


Нюанс по коду:

Он должен возвращать вот такие элементы:

PHP:
скопировать код в буфер обмена
  1. (
  2.     [0] => Array
  3.         (
  4.             [disposition] => ANSWERED
  5.             [callid] => 1
  6.             [agent] => a1
  7.             [data] => 2016-07-18 15:56:31
  8.         )


В вашем коде он возвращает:

PHP:
скопировать код в буфер обмена
  1. (
  2.     [1] => 2016-07-18 15:56:31
8. bkmz1984 - 21 Июля, 2016 - 12:31:36 - перейти к сообщению
Немного преобразовав код получил вот такой.

PHP:
скопировать код в буфер обмена
  1. $out = array();
  2. foreach ($data_result as $row){
  3.     $id = $row['callid'];
  4.     if (isset($out[$id])){
  5.         if ($out[$id]['data'] > $row['data']){
  6.             $out[$id] = $row;
  7.         }
  8.     } else {
  9.         $out[$id] = $row;
  10.     }
  11. }


И он делает как раз то что нужно, если не брать во внимание что ключи не 0,1,2,3,4 а с пропусками 1,2,4,8.

Проверяю скорость выполнения. Ваш быстрей вроде работает.

 

Powered by ExBB FM 1.0 RC1