【问题标题】:How To Reduce and Average Total PHP Array Elements To New Size如何将 PHP 数组元素总数减少和平均到新大小
【发布时间】:2020-04-05 22:22:38
【问题描述】:

采用具有 100 个元素(所有数字)的数组并将数组大小减少到较少数量的元素,将中间/组合数字平均为新的最佳解决方案是什么?我不是指切片或裁剪。

例子:

$array = [10,20,30,40,50,60];
$final_count = 3;
$new_array = array_slimmer($array, $final_count);

输出: [15,35,55]

【问题讨论】:

  • 我相信您必须指定更多规则。那么奇数个元素呢,那里的期望结果是什么?未排序的数组,应该先排序还是不排序?
  • $final_count 可以小于总计数。数组不应该被排序。想象一下随着时间的推移股票市场的交易量。 300 天太多了,所以让我们显示 100。或者您想使用的任何数据。
  • 如果我理解正确的话,您正在寻找某种...“分组”相邻元素并提取它们的平均值?
  • 解释案例count = 5 & final_count = 2,例如

标签: php arrays


【解决方案1】:

这是基于关于breaking an array into a set number of chunks 的现有答案的解决方案:

$array = [11, 3, 45, 6, 61, 89, 22];

function array_slimmer(array $array, int $finalCount): array
{
    // no work to be done if we're asking for equal or more than what the array holds
    // same goes if we're asking for just one array or (nonsensical) less
    if ($finalCount >= count($array) || $finalCount < 2) {
        return $array;
    }
    return array_map(function (array $chunk) {
        // rounded to two decimals, but you can modify to accommodate your needs
        return round(array_sum($chunk) / count($chunk), 2);
    }, custom_chunk($array, $finalCount));
}

// this function is from the linked answer
function custom_chunk($array, $maxrows) {
    $size = sizeof($array);
    $columns = ceil($size / $maxrows);
    $fullrows = $size - ($columns - 1) * $maxrows;

    for ($i = 0; $i < $maxrows; ++$i) {
        $result[] = array_splice($array, 0, ($i < $fullrows ? $columns : $columns - 1));
    }
    return $result;
}

print_r(array_slimmer($array, 2));
print_r(array_slimmer($array, 3));
print_r(array_slimmer($array, 4));

这个输出:

Array ( [0] => 16.25 [1] => 57.33 ) 
Array ( [0] => 19.67 [1] => 33.5 [2] => 55.5 )
Array ( [0] => 7 [1] => 25.5 [2] => 75 [3] => 22 )

Demo

【讨论】:

  • 不知道为什么我的答案得到了赞成而你的没有,但让我来解决这个问题......
  • @Nick 因为我显然更快(在投票时)。
  • 啊...我认为可能是这种情况... :) 我认为有两种不同的方法来处理奇数个值的情况很好;我可以看到每种方法都相关的案例。
【解决方案2】:

您可以使用array_chunk 将您的数组拆分为多个块,大小为count($array) / $final_count,然后使用array_map 从每个块中获取平均值(array_sum($chunk) / count($chunk)):

$array = [10,20,30,40,50,60];
$final_count = 3;

$new_array = array_map(function ($a) {
    return array_sum($a) / count($a);
}, array_chunk($array, (int)(count($array) / $final_count)));

print_r($new_array);

输出

Array
(
    [0] => 15
    [1] => 35
    [2] => 55
)

Demo on 3v4l.org

注意

如果数组长度不能被$final_count (demo) 整除,这将在最后给出额外的值。在这种情况下,您需要使用这样的代码将数组填充到该长度的倍数,该代码复制数组中的最后一个值:

while (count($array) % $final_count != 0) {
    $array[] = end($array);
}

Demo on 3v4l.org

【讨论】:

  • 这为问题中的示例提供了一个很好的结果,但不是failsafe
  • @El_Vanja 感谢您指出这一点。正如我在答案的后半部分中描述的那样,可以通过填充数组来解决。
猜你喜欢
  • 1970-01-01
  • 2014-06-05
  • 2017-12-08
  • 2022-07-06
  • 2012-05-08
  • 2018-09-01
  • 1970-01-01
  • 2019-08-28
  • 1970-01-01
相关资源
最近更新 更多