Как мне умножить значения многомерного массива на веса и суммировать результаты в новый массив в PHP или в целом?
Скучный способ выглядит так:
$weights = array(0.25, 0.4, 0.2, 0.15);
$values = array
(
array(5,10,15),
array(20,25,30),
array(35,40,45),
array(50,55,60)
);
$result = array();
for($i = 0; $i < count($values[0]); ++$i) {
$result[$i] = 0;
foreach($weights as $index => $thisWeight)
$result[$i] += $thisWeight * $values[$index][$i];
}
Есть ли более элегантное решение?






Хм ...
foreach($values as $index => $ary )
$result[$index] = array_sum($ary) * $weights[$index];
Думаю, вы неправильно поняли мой вопрос: я хочу получить массив взвешенных сумм, а не сумму всех сумм. Это означает, что $ result имеет размер 1xcount ($ values [0]).
Я тоже сначала неправильно понял вопрос.
Я предполагаю, что с таким представлением данных любой другой выбор будет менее ясным, чем то, что есть у вас.
Если бы мы могли изменить его на что-то другое, например, если бы мы должны были транспонировать матрицу и умножить наоборот, тогда было бы очень легко получить более лаконичный и, вероятно, элегантный способ.
<?php
$weights = array(0.2,0.3,0.4,0.5);
$values = array(array(1,2,0.5), array(1,1,1), array(1,1,1), array(1,1,1));
$result = array();
for($i = 0; $i < count($values[0]); ++$i) {
$result[$i] = 0;
foreach($weights as $index => $thisWeight) {
$result[$i] += $thisWeight * $values[$index][$i];
}
}
print_r($result);
$result = call_user_func_array("array_map",array_merge(array("weightedSum"),$values));
function weightedSum() {
global $weights;
$args = func_get_args();
return array_sum(array_map("weight",$weights,$args));
}
function weight($w,$a) {
return $w*$a;
}
print_r($result);
?>
Конечно, это зависит от того, что вы подразумеваете под элегантным.
function weigh(&$vals, $key, $weights) {
$sum = 0;
foreach($vals as $v)
$sum += $v*$weights[$key];
$vals = $sum;
}
$result = $values;
array_walk($result, "weigh", $weights);
Обновлено: Извините, что не читал ваш пример лучше. Результат делаю копию значений, т.к. array_walk работает по ссылке.
Он не об этом просит.
Это если убрать последний array_sum. Я сделаю это сейчас.
А куда делся другой ответ?