52

I am using the following loop to add items to an an array of mine called $liste. I would like to know if it is possible somehow not to add $value to the $liste array if the value is already in the array? Hope I am clear. Thank you in advance.

$liste = array();
foreach($something as $value){
     array_push($liste, $value);
}
Marc
  • 8,477
  • 18
  • 65
  • 86
  • This is a bit vague on details. It kind of depends on what `$value` is. Is it a scalar value? Is it consistently an integer? a string? Depending on this vital detail, there may be more efficient ways than to make iterated calls of `in_array()`. – mickmackusa Nov 29 '21 at 00:57

9 Answers9

111

You check if it's there, using in_array, before pushing.

foreach($something as $value){
    if(!in_array($value, $liste, true)){
        array_push($liste, $value);
    }
}

The ,true enables "strict checking". This compares elements using === instead of ==.

gen_Eric
  • 214,658
  • 40
  • 293
  • 332
  • 2
    Be aware that, if `$value` is numeric and happens to be the same as one of the (numeric) keys in `$liste`, `in_array()` can return `true` even if no such value is in the array. I suggest using `array_search()` instead and strong-comparing the result against `false`. – Jazz Apr 10 '12 at 20:37
  • 4
    @Jazz: What are you talking about? `in_array` only searches array values, not keys. http://ideone.com/JjkuP – gen_Eric Apr 10 '12 at 20:51
  • @Rocket, I see your results, but in the past I have received different results. It may be that the issue was fixed before 5.2.11. – Jazz Apr 10 '12 at 22:32
  • 1
    @Jazz: That was never an issue, not even in PHP 4. The issue was probably in your code. – gen_Eric Apr 10 '12 at 22:39
  • @Rocket, See [this link](http://us2.php.net/manual/en/function.in-array.php#106319) or [this link](http://us2.php.net/manual/en/function.in-array.php#101976) for people who have experienced issues with `in_array()`. – Jazz Apr 10 '12 at 22:40
  • @Jazz: Heh, interesting. Those issues can be fixed by adding `,true` to `in_array` to enable "strict checking". Also, those issues have *nothing* to do with the keys in the array, they have to do with PHP's weird "type juggling". P.S. `array_search` will have the same issue(s). – gen_Eric Apr 10 '12 at 22:42
  • 3
    @Rocket, I went back and looked. You are correct that I am mischaracterizing the issue with `in_array()` -- it does not have issues with numeric keys, but with loose type conversion. My mistake! In the code where I used it before, using strict mode was not an option (I needed `'2'` to compare the same as `2` but not the same as `'2thing'`). I still recommend that new PHP developers use `array_search()` if only because it has fewer "gotcha's" than `in_array().` The moral is -- whatever you use, make sure you know when it won't work. – Jazz Apr 10 '12 at 22:46
  • @Jazz: `array_search` has the same "gotcha's" as `in_array`, though. – gen_Eric Apr 10 '12 at 22:49
29

Two options really.

Option 1: Check for each item and don't push if the item is there. Basically what you're asking for:

foreach($something as $value) {
    if( !in_array($value,$liste)) array_push($liste,$value);
}

Option 2: Add them anyway and strip duplicates after:

foreach($something as $value) {
    array_push($liste,$value);
}
$liste = array_unique($liste);

By the look of it though, you may just be looking for $liste = array_unique($something);.

Niet the Dark Absol
  • 311,322
  • 76
  • 447
  • 566
8

As this question is using not the best practice code to begin with - I find all the answers here to be over-complicated.

Solving code in question:

Basically what is tried to do in question itself is filtering out repetitions. Better approach:

$liste = array_unique($something);

If adding elements to an array that is not empty:

$liste = array_unique(array_merge($liste, $something));

If you are using array_push():

Unless you are actually using return value of array push you should really use:

$liste[] = $value;

for shorter syntax and minor performance increase

NoOorZ24
  • 2,370
  • 1
  • 11
  • 30
5

The right answer is much simpler. Push everything, but then use array_unique() function:

array_push($array, $new_member);
$array = array_unique($array);
Nick
  • 207
  • 3
  • 10
4

maybe you want to use it as an associative array instead. it's implemented as (something like) a hash table, so you get constant insert time instead of linear.

function find_uniq( $something ) {
    foreach($something as $value){
         $liste[$value]++;
    }
    return array_keys( $liste );
}
bjelli
  • 9,060
  • 4
  • 32
  • 48
3

You can simply check this condition before calling array_push(). Use array_search() and use a strong comparison to false to see if the value is present:

foreach( $something as $value ){
    if( array_search( $value, $liste, true ) === false ){
        array_push( $liste, $value );
    }
}

(By the way: Add ,true to array_search to use "strict checking". This will use === for comparisons instead of ==)

gen_Eric
  • 214,658
  • 40
  • 293
  • 332
Jazz
  • 1,355
  • 1
  • 14
  • 23
  • I don't know where you heard that info about `in_array`, but it's completely wrong. `in_array` *only* searches **values**, not **keys**. http://ideone.com/JjkuP – gen_Eric Apr 10 '12 at 20:58
  • 1
    @Rocket, I see your results, but in the past I have received different results. It may be that the issue was fixed before 5.2.11. – Jazz Apr 10 '12 at 22:30
  • @Jazz: You must have done something wrong in your code, that was never an issue, not even in PHP 4. – gen_Eric Apr 10 '12 at 22:37
  • @Rocket, See [this link](http://us2.php.net/manual/en/function.in-array.php#106319) or [this link](http://us2.php.net/manual/en/function.in-array.php#101976) for people who have experienced issues with `in_array()`. I can assure you that when I encountered this issue about three years ago, I verified quite thoroughly that the issue was not in my code. – Jazz Apr 10 '12 at 22:41
  • @Jazz: Those issues have *nothing* to do with the keys in the array, they have to do with PHP's weird "type juggling". `array_search` will have the same issue(s). You need to add `,true` to enable "strict checking" to fix this. Otherwise it uses `==` to compare (and `'2dudes' == 2`). – gen_Eric Apr 10 '12 at 22:46
  • @Jazz: I edited your answer with the results of our discussion :-) – gen_Eric Apr 10 '12 at 22:52
1

Great answers are already present above, but if you have multiple array_push() all over your code, it would be a pain to write if(in_array()) statements every time.

Here's a solution that will shorten your code for that case: Use a separate function.

function arr_inserter($arr,$add){ //to prevent duplicate when inserting
    if(!in_array($add,$arr))
        array_push($arr,$add);
    return $arr;
}

Then in all your array_push() needs, you can call that function above, like this:

$liste = array();
foreach($something as $value){
    $liste = arr_inserter($liste, $value);
}

If $value is already present, $liste remains untouched.

If $value is not yet present, it is added to $liste.

Hope that helps.

ITWitch
  • 1,589
  • 4
  • 19
  • 36
1

Save logic and improve speed by keeping it logic-less. Just keep overwriting.

$list = array();
foreach ($something as $value) {
  if (!is_object($value) && !is_array($value)) {
    $list[$value] = $value
  }
}
$list = array_values($list);
doublejosh
  • 5,255
  • 4
  • 35
  • 45
  • This works fine, as long as $value (as key) is not an object or array – gradosevic Oct 20 '16 at 17:35
  • 1
    This is a pretty decent solution, but you can see that you no longer have a logic-less solution, right? After the latest edit, this does not seem to be the most elegant solution anymore. – David Nov 22 '17 at 15:43
  • That's true it does include some logic in each loop now :( I'd need to see some perf testing to know if this is the right approach. – doublejosh Nov 30 '17 at 01:30
  • While this can be efficient, there are some fringe cases whereby key collisions will damage the data. For one instance, floats will be truncated to integers -- so data loss is possible. `is_scalar()` will improve the "elegance". – mickmackusa Jul 17 '21 at 10:53
1

I have another solution for you! You can use keys as values And keys will never be duplicated.

$arr = ["A" => true, "B" => true, "C" => true];

$item = "A";
$arr[$item] = true;

Usage:

foreach($arr as $value => $helper){
    echo $value;
}

Set class

OK, Let me write a class for you! The arrays do not allow duplicated items are called sets.

class Set{
    private $countainer;

    public function get(){
        return $this->container;
    }
    public function push($item){
        $this->container[$item] = true;
    }
    public function delete($item){
        unset($this->container[$item]);
    }
}

Note: This will not work for associative arrays and values.

Amir Fo
  • 4,077
  • 1
  • 36
  • 44