Я сделал поиск, но безуспешно. Я всегда получаю какую-то ошибку... Я хочу получить среднее значение значений «Импорт», сгруппированных по дате.
Я ценю, если кто-то может мне помочь...
Мой файл JSON:
[
{
"Date": "2019-03",
"Import": "200",
"Export": "50"
},
{
"Date": "2019-03",
"Import": "800",
"Export": "200"
},
{
"Date": "2019-04",
"Import": "100",
"Export": "600"
}
]
Мой PHP-скрипт:
$url = dirname(__DIR__ ) . '/admin/json/all.json';
$json = file_get_contents($url);
$array_origin = json_decode($json, TRUE);
$stack=array();
foreach ($array_origin as $v) {
$stack[$v['Date']]['Import'] = isset($v['Date']) ? $stack[$v['Date']]['Import'] + $v['Import'] : $v['Import'];
$stack[$v['Date']]['Export'] = isset($v['Date']) ? $stack[$v['Date']]['Export'] + $v['Export'] : $v['Export'];
$stack[$v['Date']]['Average_Import'] = 'GET HERE AVERAGE';
}
echo '<pre>' . var_export($stack, true) . '</pre>';
Заранее спасибо. Ваше здоровье
Извините, забыл добавить в код :) $stack=array();
I always get some error.
- какой?
What I want is, get the average of the values "Import"
Простой
$array_origin = json_decode('[
{
"Date": "2019-03",
"Import": "200",
"Export": "50"
},
{
"Date": "2019-03",
"Import": "800",
"Export": "200"
},
{
"Date": "2019-04",
"Import": "100",
"Export": "600"
}
]', true);
echo round(array_sum(array_column($array_origin, 'Import'))/count($array_origin));
Выход
367
Это совокупное значение всех строк, поэтому нет особого смысла хранить его в каждой из строк.
Если не во всех строках есть Import
, вы можете просто сделать столбец переменной и вместо этого подсчитать это:
$import = array_column($array_origin, 'Import'); //["200","800","100"]
echo round(array_sum($import)/count($import));
ОБНОВИТЬ Пока это было не ясно
No, because as you see, have a filter "by date". You are printing all itens, not by date. :( –
Это все еще тривиальная проблема (если вы знаете, сколько предметов и их общее количество).
$stack = [];
foreach ($array_origin as $v) {
$key = $v['Date'];
if (!isset($stack[$key])) $stack[$key] = [];
$stack[$key]['Import'] = isset($stack[$key]['Import']) ? $stack[$key]['Import'] + $v['Import'] : $v['Import'];
$stack[$key]['Export'] = isset($stack[$key]['Export']) ? $stack[$key]['Export'] + $v['Export'] : $v['Export'];
//track the number of items
$stack[$key]['items'] = isset($stack[$key]['items'] ) ? ++$stack[$key]['items'] : 1;
$stack[$key]['Average_Import'] = 'GET HERE AVERAGE';
}
//cant average tell you know what they are, this will have to be done after the foreach
array_walk($stack,function(&$item){
$item['Average_Import'] = $item['Export']/$item['items'];
return $item;
});
print_r ($stack);
Выход
Array
(
[2019-03] => Array
(
[Import] => 1000
[Export] => 250
[items] => 2
[Average_Import] => 125
)
[2019-04] => Array
(
[Import] => 100
[Export] => 600
[items] => 1
[Average_Import] => 600
)
)
Кроме того, этот цикл foreach
был просто завален проблемами, поэтому я их исправил. В основном мелочи...
Например:
isset($v['Date']) ? $stack[$v['Date']]['Import'] + $v['Import']
Это никак не предотвращает добавление ошибок чтения для этого значения ['Import']
. Это isset($v['Date'])
может быть верным в течение всего дня, и это ничего не говорит нам о том, установлено ли $stack[$v['Date']]['Import']
или нет. Если он не установлен, и мы пытаемся прочитать его для добавления (нужно знать его значение, чтобы добавить к нему), мы получим уведомление о неопределенном индексе.
Теперь Если вы не хотите отслеживать количество этих предметов (по какой-то причине)
Это хороший трюк (плюс его забава), чтобы получить количество элементов на заданную дату:
$num_dates = array_count_values(array_column($array_origin, 'Date'));
Выход
Array
(
[2019-03] => 2
[2019-04] => 1
)
Это даст вам эту информацию. Затем используйте $num_dates
в обратном вызове (буквально, каламбур) и key
элемента:
foreach ($array_origin as $v) {
$key = $v['Date'];
if (!isset($stack[$key])) $stack[$key] = [];
$stack[$key]['Import'] = isset($stack[$key]['Import']) ? $stack[$key]['Import'] + $v['Import'] : $v['Import'];
$stack[$key]['Export'] = isset($stack[$key]['Export']) ? $stack[$key]['Export'] + $v['Export'] : $v['Export'];
$stack[$key]['Average_Import'] = 'GET HERE AVERAGE';
}
$num_dates = array_count_values(array_column($array_origin, 'Date'));
array_walk($stack,function(&$item,$key)use($num_dates){
//may want to check if $key exists (but it should always)
$item['Average_Import'] = $item['Export']/$num_dates[$key];
return $item;
});
Выход
Array
(
[2019-03] => Array
(
[Import] => 1000
[Export] => 250
[Average_Import] => 125
)
[2019-04] => Array
(
[Import] => 100
[Export] => 600
[Average_Import] => 600
)
)
Это не работает? 200 + 800 + 100 = 1100 / 3 = 366.66666
Нет, потому что, как видите, есть фильтр "по дате". Вы печатаете все itens, а не по дате. :(
Нет, я не вижу, так как это никогда не упоминается в вопросе. Может быть, у вас есть это $stack[$v['Date']]['Import']
что это значит для меня? Это то, о чем вы просили What I want is, get the average of the values "Import"
, а не What I want is, get the average of the values "Import" [grouped by date]
слова имеют значение.
Да, вы правы, я только что обновил тему. Извиняюсь.
Исправлено вашим скриптом. Спасибо за ваше время :)
Конечно, это было весело... Я люблю манипулировать массивами (по какой-то странной причине).
$array_origin = json_decode('[
{
"Date": "2019-03",
"Import": "200",
"Export": "50"
},
{
"Date": "2019-03",
"Import": "800",
"Export": "200"
},
{
"Date": "2019-04",
"Import": "100",
"Export": "600"
}
]', true);
$counts = [];
$imports = [];
foreach ($array_origin as $data) {
if (isset($data['Import']) && isset($data['Date'])) {
if (!isset($counts[$data['Date']])) {
$counts[$data['Date']] = 0;
$imports[$data['Date']] = 0;
}
$counts[$data['Date']]++;
$imports[$data['Date']] = intval($data['Import']) + $imports[$data['Date']];
}
}
$importAverage = [];
foreach ($imports as $date => $importSum) {
$importAverage[$date] = $importSum > 0 ? $importSum / $counts[$date] : 0;
}
var_dump($importAverage);
array (size=2)
'2019-03' => int 500
'2019-04' => int 100
что такое $стек?