IceFire
IceFire

Reputation: 4147

Short way to set or add numeric value of associative array?

Is there a shorter way to accomplish the following?

<?php
    $arr = [];

    // ...

    if(isset($arr['key']))
        $arr['key'] += 10;
    else
        $arr['key'] = 10;
?>

Upvotes: 0

Views: 76

Answers (4)

Markus AO
Markus AO

Reputation: 4889

If you're using PHP7, you can take advantage of the new ?? null coalescing operator. ("...returns its first operand if it exists and is not NULL; otherwise it returns its second operand.")

$arr['key'] = ($arr['key'] ?? 0) + 10;

What happens above: The expression in the brackets sets $arr['key'] to 0 if it isn't defined, otherwise leaves it as-is; and +10 is added to the result. This is the shortest approach.


The most common and easy-to-understand solution is using the ? : ternary operator:

$arr['key'] = isset($arr['key']) ? $arr['key'] + 10 : 10; // or:
$arr['key'] = !isset($arr['key']) ? 10 : $arr['key'] + 10;

You could also do something like this:

isset($arr['key']) && ($arr['key'] += 10) || ($arr['key'] = 10);  // or:   
!isset($arr['key']) && ($arr['key'] = 10) || ($arr['key'] += 10);

Bottom line: There's no built-in solution in PHP for "define-if-not-exists", there will be a warning if you attempt to increment a non-existing variable.

As far as some other answers here: I wouldn't use @ to suppress errors, not good practice. Keep it short, not hackish. Incurring a separate function call on each variable increment seems excessive.


For those about to micro-optimize, and for the inquiring minds who need to know; benchmarks for 10M iterations of each. When defined once and then incremented in a loop; Ex.1: 2.43 sec; Ex.2a: 2.93 sec; Ex.2b: 3.03 sec, Ex.3a: 3.12 sec, Ex.3b: 3.02 sec. ... When unset & defined in each iteration; Ex.1: 3.49 sec, Ex.2a: 3.22 sec, Ex.2b: 3.86 sec, Ex.3a: 3.78 sec, Ex.3b: 4.50sec. (For context, simply defining the variable 10M times takes 1.85 sec, and unset+redefine takes 2.67 sec.)

Null-coalescing and ternary operators will perform better due to checking the variable directly in C instead of incurring a PHP isset function call. The error-suppressing @$arr['key'] += 10; approach clocks 2.39 sec in the first test; but clocks a heavy penalty in the second when the error suppression is triggered each time; 8.34 sec; and a whopping 53.7 sec if I leave my framework's error handler on!

Upvotes: 1

Georges O.
Georges O.

Reputation: 992

You have several solutions:

Function with reference

Use & on the parameters

This imply a new call of the function for each variable. Not good for resources, only for coding style :)

<?php

function addOrDefine(&$variable, $value, $defaultValue = null) {
    if( !isset($variable) )
        $variable = $defaultValue;
    $variable += $value;

    return $variable;
}

$varA = addOrDefine($array['toto'], 10);
$varA = addOrDefine($array['toto'], 10);

var_dump($varA); // output '20'

?>

You can create a define function:

<?php
function variableDefine(&$variable, $defaultValue = null) {
    if( !isset($variable) )
        $variable = $defaultValue;
    return $variable;
}
$varA = variableDefine($varA);
$varB = variableDefine($_GET['varB'], 'defaultvalue');
?>

Another solution: simplify your syntax

<?php

if( !isset($array['toto']) ) {
  $array['toto'] = null;
}

$array['toto'] += 10;

?>

Can be simplified on:

<?php

if( !isset($array['toto']) )
  $array['toto'] = null;

$array['toto'] += 10;

?>

Or:

<?php

if( !isset($array['toto']) ) $array['toto'] = null;

$array['toto'] += 10;

?>

Assign value if the variable does not exists with default value. After, use the variable as usual.

Ternary Operator

<?php

$varA = isset($array['toto']) ? $array['toto'] : 10;

// or
// if you want to use the previous point
$array['toto'] = isset($array['toto']) ? $array['toto'] : null;
$array['toto'] += 10;

?>

$varA is the value of the variable needed, with default value if it's not existing.

Upvotes: 1

IceFire
IceFire

Reputation: 4147

@$arr['key'] += 10;

seems to be the shortest solution.

Anything to say against it? Really not sure, whether @ leads to inefficiencies

Upvotes: 1

Hikmat Sijapati
Hikmat Sijapati

Reputation: 7004

Use the ternary operator:Try it

<?php
$arr = [];
// ...
$arr['key']= isset($arr['key'])?($arr['key']+10):10;

Upvotes: 1

Related Questions