PHP подсчитывает элементы в многомерном массиве

Как видно из следующего массива, есть три элемента, которые появляются 18 ноября, и еще два элемента, которые появляются 22 ноября. Может ли кто-нибудь сказать мне, как я могу получить подсчеты 3 и 2 соответственно из этого массива? В принципе, я хочу в итоге получить что-то вроде этого:

18 ноября 2011 = 3 позиции

22 ноября 2011 = 2 позиции

Конечно, даты и количество разных дат будут меняться каждый раз. Вот массив:

Array ( [0] => Array ( [0] => Array ( [2011-11-18 00:00:00] => C ) [1] => Array ( [2011-11-18 00:00:00] => I ) [2] => Array ( [2011-11-18 00:00:00] => S ) ) [1] => Array ( [0] => Array ( [2011-11-22 00:00:00] => C ) [1] => Array ( [2011-11-22 00:00:00] => S ) ) ) 

Это работает для того, что вам нужно?

 $dates = array(array(array("2011-11-18 00:00:00" => C), array("2011-11-18 00:00:00" => I),array ("2011-11-18 00:00:00" => S)), array(array("2011-11-22 00:00:00" => C), array("2011-11-22 00:00:00" => S))); $date_count = array(); // create an empty array foreach($dates as $date) { // go thought the first level foreach($date as $d) { // go through the second level $key = array_keys($d); // get our date // here we increment the value at this date // php will see it as 0 if it has not yet been initialized $date_count[$key[0]]++; } } // show what we have print_r($date_count); 

Печать:

 Array ( [2011-11-18 00:00:00] => 3 [2011-11-22 00:00:00] => 2 ) 

Примечание: это предполагает, что вы всегда будете получать данные по мере структурирования своего массива и чтобы каждая дата была отформатирована одинаково. Если вы не можете предположить, что каждая дата будет отформатирована, это будет простым преобразованием с использованием функции date (). Если вы не можете предположить, что вы получите данные, структурированные именно так, лучший способ справиться с этим, вероятно, будет через рекурсивную функцию.

Вы можете использовать:

 count($array, COUNT_RECURSIVE); 

Подсчитать количество листов в дереве вложенных массивов

опубликованные ответы верны для вашего типичного примера, но я хотел бы добавить другое решение, которое будет работать независимо от того, сколько вложенных массивов вы можете создать. он повторяет массив рекурсивно и подсчитывает все элементы во всех подмассивах.

он возвращает общее количество элементов в массиве. во втором аргументе вы можете указать ссылку на массив, которая будет содержать счет за уникальный ключ в (вложенном) массиве.

пример:

 <?php $deeply_nested = array( 'a' => 'x', 'b' => 'x', 'c' => 'x', 'd' => array( 'a' => 'x', 'b' => 'x', 'c' => array( 'a' => 'x', 'b' => 'x' ), 'e' => 'x' ) ); function count_nested_array_keys(array &$a, array &$res=array()) { $i = 0; foreach ($a as $key=>$value) { if (is_array($value)) { $i += count_nested_array_keys($value, &$res); } else { if (!isset($res[$key]) $res[$key] = 0; $res[$key]++; $i++; } } return $i; } $total_item_count = count_nested_array_keys($deeply_nested, $count_per_key); echo "total count of items: ", $total_item_count, "\n"; echo "count per key: ", print_r($count_per_key, 1), "\n"; 

результаты:

 total count of items: 8 count per key: Array ( [a] => 3 [b] => 3 [c] => 1 [e] => 1 ) 

Предполагая, что пример массива является репрезентативным:

 foreach ($array as $key => $value) { echo count($value) . "<br />"; } 

Будет отображать количество массивов в каждом из основных элементов массива. В вашем примере это также будет количество записей для каждой даты.

Это, конечно, не проверяет сами даты

Вы можете использовать array_walk_recursive() чтобы получить доступ ко всем узлам листа в структуре массива.

Что-то похожее на это должно сработать для вас:

 <?php $data = array( array( array('2011-11-18 00:00:00' => 'C'), array('2011-11-18 00:00:00' => 'I'), array('2011-11-18 00:00:00' => 'S')), array( array('2011-11-22 00:00:00' => 'C'), array('2011-11-22 00:00:00' => 'S'))); function countleafkeys($value, $key, $userData) { echo "$key\n"; if(!isset($userData[$key])) { $userData[$key] = 1; } else { $userData[$key]++; } } $result = array(); array_walk_recursive($data, 'countleafkeys', &$result); print_r($result); 

Выходы:

 2011-11-18 00:00:00 2011-11-18 00:00:00 2011-11-18 00:00:00 2011-11-22 00:00:00 2011-11-22 00:00:00 Array ( [2011-11-18 00:00:00] => 3 [2011-11-22 00:00:00] => 2 ) 

Для вашей конкретной структуры $array я думаю, что самый бережливый способ – использовать foreach а затем получать значение даты и count() из каждого значения:

 $dateCounts = array(); foreach($array as $date) { $dateCounts[key($date[0])] = count($date); } var_dump($dateCounts); 

С вашим $array это дает:

 array(2) { ["2011-11-18 00:00:00"]=> int(3) ["2011-11-22 00:00:00"]=> int(2) } 

Если вы ищете более общий способ, вы можете использовать RecursiveArrayIterator и RecursiveIteratorIterator для перемещения по всем элементам листа / значения листа, а затем просто подсчитывать ключи:

 $it = new RecursiveIteratorIterator(new RecursiveArrayIterator($array)); $keyCounts = array(); foreach ($it as $key => $value) { isset($keyCounts[$key]) ? $keyCounts[$key]++ : $keyCounts[$key] = 1; } var_dump($keyCounts); 

Надеюсь это поможет.

Вот мой рекурсивный вариант:

 $arr = array( '0' => array( '0' => array('2011-11-18 00:00:00' => 'C'), '1' => array('2011-11-18 00:00:00' => 'I'), '2' => array('2011-11-18 00:00:00' => 'S') ), '1' => array( '0' => array('2011-11-22 00:00:00' => 'C'), '1' => array('2011-11-22 00:00:00' => 'S') ), '2' => array( '0' => array( '0' => array('2011-11-22 00:00:00' => 'D') ) ) ); function count_values($array, &$result = array(), $counter = 0) { foreach ($array as $key => $data) { if (is_array($data)) { count_values($data, $result, $counter); } else { array_key_exists($key, $result) ? $result[$key]++ : $result[$key] = 1; } } return $result; } print_r(count_values($arr)); 

Это вернет:

 Array ( [2011-11-18 00:00:00] => 3 [2011-11-22 00:00:00] => 3 ) 
 <?php $count0=count($array[0], COUNT_RECURSIVE)-count($array[0]); $count1=count($array[1], COUNT_RECURSIVE)-count($array[1]); 

Если вы хотите считать элементы одномерными и двумерными, вы можете попробовать:

 echo 'Size of unidimensional is: '.count($celda).'<br/>'; echo 'Size of bidimensional is: '.count($celda[0]).'<br/>';