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
)
)
)
9 ответов
работает ли это для того, что вам нужно?
$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 (). Если вы не можете предположить, что получите данные, структурированные точно так же, лучший способ решить эту проблему, вероятно, будет через рекурсивный функция.
опубликованные ответы верны для вашего репрезентативного примера, но я хотел бы добавить другое решение, которое будет работать независимо от того, сколько вложенных массивов вы можете создать. он перебирает массив и рекурсивно подсчитывает все элементы во всех подмассивов.
это возвращает общее количество элементов в массиве. во втором аргументе можно указать массив ссылка, которая будет содержать количество на уникальный ключ в (вложенном) массив(ы).
пример:
<?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
чтобы пересечь все элементы leaf key / value, а затем просто подсчитать ключи:
$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/>';