У меня есть php-массив:
Array ( [0] => Array ( [url_id] => 2191238 [time_spent] => 41 ) [1] => Array ( [url_id] => 2191606 [time_spent] => 215 ) [2] => Array ( [url_id] => 2191606 [time_spent] => 25 ) )
Итак, как получить SUM of time_spent
на основе группы по url_id (используя array_count_values)
Почему не проще
$ts_by_url = array(); foreach($array as $data) { $ts_by_url[ $data['url_id'] ] += $data['time_spent']; }
Давайте притворимся, что $array
содержит наши данные. Мы пройдем через массив и постоянно добавим time_spent
к другому массиву с ключом url_id
.
$ts_by_url = array(); foreach($array as $data) { if(!array_key_exists($data['url_id'], $ts_by_url)) $ts_by_url[ $data['url_id'] ] = 0; $ts_by_url[ $data['url_id'] ] += $data['time_spent']; }
$ts_by_url
теперь должен содержать:
2191238 => 41 2191606 => 240 // == 215 + 25
ОП опубликовала интересную проблему, но предложение использовать array_count_values () не применимо; функция не суммирует значения массива, а подсчитывает их частоту. Ответ @marcocassisa работает, но недостаточен из-за неудачной эмиссии E_NOTICES, хотя и не имеет отношения к какой-либо математической проблеме. (Неопределенная переменная не задана и, следовательно, имеет значение NULL, но в математическом контексте она будет временно принудительно введена в нуль.) Современный PHP не рекомендует использовать неопределенные переменные путем намеренного повышения уведомлений при использовании кода с одним исключением, начиная с с PHP 5.1: оператор, состоящий только из неопределенной переменной; см. здесь .
Чтобы исправить вышеупомянутое решение, можно использовать две петли foreach , одну для установки индексных ключей и инициализацию элементов массива, в то время как другая будет выполнять суммирование значений следующим образом:
<?php // set keys and initialize foreach($arr as $data) { $its_by_url[ $data["url_id"] ] = 0; } // now can sum values by url id number: foreach($arr as $data) { $its_by_url[ $data["url_id"] ] += $data["time_spent"]; }
см. демо .
Несмотря на то, что это удовлетворительное решение, это решение не имеет элегантности. Попытка объединить две петли foreach в одну, будет отрицательно воздействовать на второй элемент, поскольку он определяется, а затем бесполезно переопределяется. Для ответа @Charles можно создать код и создать индекс нумерации идентификаторов URL, если он еще не существует. Или вы можете проверить, установлено ли оно следующим образом:
<?php foreach($arr as $data) { if ( !isset( $its_by_url[ $data["url_id"] ] ) ) { $its_by_url[ $data["url_id"] ] = 0; } $its_by_url[ $data["url_id"] ] += $data["time_spent"]; }
см. демо
Примечание: если элемент массива был определен как null, то isset () вернет значение false, а array_key_exists () вернет true. Пер, Илья Альшанецкий
… если вашему приложению не нужно различать ключ массива, который не существует, а тот, значение которого имеет значение NULL, вы должны использовать isset (), потому что это происходит немного быстрее.