[php] add to array if it isn't there already

How do I add elements to an array only if they aren't in there already? I have the following:

$a=array();
// organize the array
foreach($array as $k=>$v){
    foreach($v as $key=>$value){
        if($key=='key'){
        $a[]=$value;
        }
    }
}

print_r($a);

// Output

Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 1
[4] => 2
[5] => 3
[6] => 4
[7] => 5
[8] => 6

)

Instead, I want $a to consist of the unique values. (I know I can use array_unique to get the desired results but I just want to know)

This question is related to php

The answer is


You should use the PHP function in_array (see http://php.net/manual/en/function.in-array.php).

if (!in_array($value, $array))
{
    $array[] = $value; 
}

This is what the documentation says about in_array:

Returns TRUE if needle is found in the array, FALSE otherwise.


Try this code, I got it from here

$input = Array(1,2,3,1,2,3,4,5,6);
$input = array_map("unserialize", array_unique(array_map("serialize", $input)));

if (!in_array($value, $a))
  $a[]=$value;

Try adding as key instead of value:

Adding an entry

function addEntry($entry) {
    $this->entries[$entry] = true;
}

Getting all entries

function getEntries() {
    return array_keys($this->enties);
}

Taking Gumbo's idea, making the code work:

$array = array('111111','222222','3333333','4444','5555', 
'AAAAAA', 'BBBBBB', 'CCC', 'DDDDDDD', 'EEEEEEEE', 'FFFFFF', 'GGG',
'AAAAAA', 'BBBBBB', 'CCC', 'DDDDDDD', 'EEEEEEEE', 'FFFFFF', 'GGG',
'222222', 
'666666', '777777', 'HHHH');

print_r($array);

$keys= array();
foreach ($array as $k => $v){
    if (isset($v['value'])) {
        $keys[$v] = $k;
    }
}
$unique = array();
foreach ($keys as $key) {
    $unique[] = $array[$key];
}
print "<br><br>";
print_r($unique);

Gives this:

Array
(
    [0] => 111111
    [1] => 222222
    [2] => 3333333
    [3] => 4444
    [4] => 5555
    [5] => AAAAAA
    [6] => BBBBBB
    [7] => CCC
    [8] => DDDDDDD
    [9] => EEEEEEEE
    [10] => FFFFFF
    [11] => GGG
    [12] => AAAAAA
    [13] => BBBBBB
    [14] => CCC
    [15] => DDDDDDD
    [16] => EEEEEEEE
    [17] => FFFFFF
    [18] => GGG
    [19] => 222222
    [20] => 666666
    [21] => 777777
    [22] => HHHH
)

Array
(
    [0] => 111111
    [1] => 222222
    [2] => 3333333
    [3] => 4444
    [4] => 5555
    [5] => AAAAAA
    [6] => BBBBBB
    [7] => CCC
    [8] => DDDDDDD
    [9] => EEEEEEEE
    [10] => FFFFFF
    [11] => GGG
    [12] => 666666
    [13] => 777777
    [14] => HHHH
)

With array_flip() it could look like this:

$flipped = array_flip($opts);
$flipped[$newValue] = 1;
$opts = array_keys($flipped);

With array_unique() - like this:

$opts[] = $newValue;
$opts = array_values(array_unique($opts));

Notice that array_values(...) — you need it if you're exporting array to JavaScript in JSON form. array_unique() alone would simply unset duplicate keys, without rebuilding the remaining elements'. So, after converting to JSON this would produce object, instead of array.

>>> json_encode(array_unique(['a','b','b','c']))
=> "{"0":"a","1":"b","3":"c"}"

>>> json_encode(array_values(array_unique(['a','b','b','c'])))
=> "["a","b","c"]"

Since you seem to only have scalar values an PHP’s array is rather a hash map, you could use the value as key to avoid duplicates and associate the $k keys to them to be able to get the original values:

$keys = array();
foreach ($array as $k => $v){
    if (isset($v['key'])) {
        $keys[$value] = $k;
    }
}

Then you just need to iterate it to get the original values:

$unique = array();
foreach ($keys as $key) {
    $unique[] = $array[$key]['key'];
}

This is probably not the most obvious and most comprehensive approach but it is very efficient as it is in O(n).

Using in_array instead like others suggested is probably more intuitive. But you would end up with an algorithm in O(n2) (in_array is in O(n)) that is not applicable. Even pushing all values in the array and using array_unique on it would be better than in_array (array_unique sorts the values in O(n·log n) and then removes successive duplicates).


If you're okay with using shorthands in your code (instead of writing explicit if blocks, like some coding standards recommend), you can further simplify Marius Schulz's answer with this one-liner:

in_array ($value, $array) || $array [] = $value;

Since there are a ton of ways to accomplish the desired results and so many people provided !in_array() as an answer, and the OP already mentions the use of array_unique, I would like to provide a couple alternatives.

Using array_diff (php >= 4.0.1 || 5) you can filter out only the new array values that don't exist. Alternatively you can also compare the keys and values with array_diff_assoc. http://php.net/manual/en/function.array-diff.php

$currentValues = array(1, 2);
$newValues = array(1, 3, 1, 4, 2);
var_dump(array_diff($newValues, $currentValues));

Result:

Array
(
    [1] => 3
    [3] => 4
)

http://ideone.com/SWO3D1

Another method is using array_flip to assign the values as keys and compare them using isset, which will perform much faster than in_array with large datasets. Again this filters out just the new values that do not already exist in the current values.

$currentValues = [1, 2];
$newValues = [1, 3, 1, 4, 2];
$a = array();
$checkValues = array_flip($currentValues);
foreach ($newValues as $v) {
    if (!isset($checkValues[$v])) {
        $a[] = $v;
    }
}

Result:

Array
(
    [0] => 3
    [1] => 4
)

http://ideone.com/cyRyzN

With either method you can then use array_merge to append the unique new values to your current values.

  1. http://ideone.com/JCakmR
  2. http://ideone.com/bwTz2u

Result:

Array
(
    [0] => 1
    [1] => 2
    [2] => 3
    [3] => 4
)

If you don't care about the ordering of the keys, you could do the following:

$array = YOUR_ARRAY
$unique = array();
foreach ($array as $a) {
    $unique[$a] = $a;
}

you can try using "in_array":

function insert_value($value, &$_arr) {
    if (!in_array($value, $_arr)) {
        $_arr[] = $value;
    }
}

Easy to write, but not the most effective one:

$array = array_unique(array_merge($array, $array_to_append));

This one is probably faster:

$array = array_merge($array, array_diff($array_to_append, $array));

if (!in_array(...))  
  array_push(..)