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)
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.
Result:
Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
)
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;
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"]"
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
)
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).
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)));