81

Example:

$a[] = '56';
$a[] = '66';
$a[] = '';
$a[] = '58';
$a[] = '85';
$a[] = '';
$a[] = '';
$a[] = '76';
$a[] = '';
$a[] = '57';

Actually how to find average value from this array excluding empty. please help to resolve this problem.

Dinesh G
  • 1,325
  • 4
  • 17
  • 24
  • 4
    You should not define integers as strings. Instead of `$a[] = '56';` it should be `$a[] = 56;` – Avatar Jun 06 '19 at 07:23

4 Answers4

163

first you need to remove empty values, otherwise average will be not accurate.

so

$a = array_filter($a);
$average = array_sum($a)/count($a);
echo $average;

DEMO

More concise and recommended way

$a = array_filter($a);
if(count($a)) {
    echo $average = array_sum($a)/count($a);
}

See here

Mubin
  • 4,325
  • 5
  • 33
  • 55
  • 8
    Keep in mind that you should first check to ensure count() is positive, otherwise you'll get a divide by zero error – Shane N Oct 05 '17 at 21:14
  • 9
    array_filter would remove zeros also, skewing the average. – Milo LaMar Mar 23 '19 at 08:49
  • 1
    @MiloLaMar: yes, for that please check Don't Panic's answer below. – Mubin Mar 23 '19 at 13:13
  • You should make `count` check AFTER you've filtered out empty values – Oleg Jul 26 '19 at 05:24
  • The double use of the `count()` an add some needless overhead from calling `count()` multiple times. You can either do `$count = count($a);` or just do `if($a)`. Both are good enough solutions. I would use `if($a)` which saves on calling `count()` on empty arrays, but is harder to understand for those starting to learn the language. – Ismael Miguel Jun 29 '20 at 10:37
26

The accepted answer works for the example values, but in general simply using array_filter($a) is probably not a good idea, because it will filter out any actual zero values as well as zero length strings.

Even '0' evaluates to false, so you should use a filter that explicitly excludes zero length strings.

$a = array_filter($a, function($x) { return $x !== ''; });
$average = array_sum($a) / count($a);
Don't Panic
  • 41,125
  • 10
  • 61
  • 80
  • With PHP 7.4+, you can do `array_filter($a, fn($x)=>$x !== '');`, using the syntax for [arrow function](https://www.php.net/manual/en/migration74.new-features.php#migration74.new-features.core.arrow-functions). – Ismael Miguel Jun 29 '20 at 10:40
7
echo array_sum($a) / count(array_filter($a));
Martyn Shutt
  • 1,671
  • 18
  • 25
1

As a late look, item controls should be done with numeric check. Otherwise something like this $array = [1.2, 0.33, [123]] will corrupt the calculation:

// Get numerics only.
$array = array_filter($array, fn($v) => is_numeric($v));

// Get numerics only where value > 0.
$array = array_filter($array, fn($v) => is_numeric($v) && ($v > 0));

Finally:

public static function average(array $array, bool $includeEmpties = true): float
{
    $array = array_filter($array, fn($v) => (
        $includeEmpties ? is_numeric($v) : is_numeric($v) && ($v > 0)
    ));

    return array_sum($array) / count($array);
}

Credits: froq.util.Arrays

Kerem
  • 11,377
  • 5
  • 59
  • 58