JSON - получить среднее значение из значений в php

Я сделал поиск, но безуспешно. Я всегда получаю какую-то ошибку... Я хочу получить среднее значение значений «Импорт», сгруппированных по дате.

Я ценю, если кто-то может мне помочь...

Мой файл 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>';

Заранее спасибо. Ваше здоровье

что такое $стек?

battlmonstr 08.04.2019 21:41

Извините, забыл добавить в код :) $stack=array();

ficolixado 08.04.2019 21:44
I always get some error. - какой?
ArtisticPhoenix 08.04.2019 21:44
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
1
3
158
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

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

ArtisticPhoenix 08.04.2019 21:45

Нет, потому что, как видите, есть фильтр "по дате". Вы печатаете все itens, а не по дате. :(

ficolixado 08.04.2019 21:47

Нет, я не вижу, так как это никогда не упоминается в вопросе. Может быть, у вас есть это $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] слова имеют значение.

ArtisticPhoenix 08.04.2019 21:49

Да, вы правы, я только что обновил тему. Извиняюсь.

ficolixado 08.04.2019 21:51

Исправлено вашим скриптом. Спасибо за ваше время :)

ficolixado 08.04.2019 22:24

Конечно, это было весело... Я люблю манипулировать массивами (по какой-то странной причине).

ArtisticPhoenix 08.04.2019 22:25
$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

Другие вопросы по теме