У меня есть следующий массив:
$array = array(
array("A",105),
array("B",125),
array("C",325),
array("D",435),
array("A",110),
array("A",115),
array("C",400),
array("D",650),
array("E",750)
);
и хотел бы выполнить некоторые операции с ним, как показано ниже:
Во-первых: для группировки одинаковых значений ключа [0] возведите их во 2-ую степень и сложите их. Для этого я написал следующий код:
$result = array();
foreach ($array as $value){
if (!array_key_exists($value[0], $result)){
$result[$value[0]] = array();
}
$result[$value[0]][] = pow($value[1],2);
}
array_walk($result, create_function('&$v,$k', '$v = array_sum($v);'));
При этом мы получаем ожидаемый результат:
Array (
[A] => 36350
[B] => 15625
[C] => 265625
[D] => 611725
[E] => 562500
)
Второе: разделить каждое из этих значений на сумму всех их вместе. Другими словами (или лучше в других числах 🙂
Sum of them all: 36350 + 15625 + 265625 + 611725 + 562500 = 1491825
затем деление:
[A] 36350 / 1491825
[B] 15625 / 1491825
...
[E] 562500 / 1491825
Итак, в итоге мы имеем что-то вроде этого:
Array (
[A] 0.0243
[B] 0.1047
...
[E] 0.3770
)
Я думал что-то в этом роде:
array_walk($result, create_function('&$v,$k', '$v = array_sum($v) / count($v);'));
но потом я понял, что это не правильно, потому что первое значение будет делиться только на то, сколько раз происходит A, второе — на вхождения B и т. д.
Таким образом, мы бы имели:
Array (
[A] => 36350 / 3 = 12116.666666667
[B] => 15625 / 1 = 15625
[C] => 265625 / 2 = 132812.5
[D] => 611725 / 2 = 305862.5
[E] => 562500 / 1 = 562500
)
То, что я ищу, является своего рода взвешенным средним арифметическим сгруппированных значений подмассивов.
Буду признателен, если кто-нибудь поможет мне найти ответ на эту проблему.
Спасибо заранее.
Если я вас правильно понимаю, вам нужно вычислить сумму квадратов перед циклом / обходом массива.
Чтобы получить доступ к нему внутри функции обратного вызова, вы можете использовать «use» в современном php (или «global» внутри функции до php5.3)
// $array = your data
$result = array(); // grouped sum of squares
foreach ( $array as list( $key, $value ) ) {
$result[$key] += $value*value;
}
$ss = array_sum(array_values($result)); // sum of squares
// array_map preserves the keys
$means = array_map(function($value) use ($ss) {return $value/$ss;}, $result);
(Я абсолютно не проверял это. Я считать замена последней строки чем-то вроде
array_walk($result, create_function('&$v,$k', 'global $ss; $v = $v/$ss;'));
тоже может сработать)
Других решений пока нет …