80

How to find if a value exists in an array and then remove it? After removing I need the sequential index order.

Are there any PHP built-in array functions for doing this?

Machavity
  • 30,841
  • 27
  • 92
  • 100
DEVOPS
  • 18,190
  • 34
  • 95
  • 118

11 Answers11

136
<?php
$my_array = array('sheldon', 'leonard', 'howard', 'penny');
$to_remove = array('howard');
$result = array_diff($my_array, $to_remove);
?>
Peter
  • 2,051
  • 1
  • 15
  • 20
  • 7
    Can remove multiple values without looping! – dfmiller Mar 04 '14 at 22:15
  • 3
    +1 avoids the tedium of checking the return value of array_search – rinogo Jul 15 '14 at 14:25
  • 2
    Seems to be more efficient, the array $to_remove can be created using an array_search or preg_grep function in case if you are using wild card search to remove elements. – Clain Dsilva Nov 12 '14 at 02:30
  • 5
    This solution is cleaner for me. However, note that it keeps indexes, so if you want to rearrange them in numerical order you'll want to do this: **array_values(array_diff($my_array, $to_remove))** – luis.ap.uyen Nov 27 '18 at 13:48
  • This should be the correct answer. If value is not found it leave's the array untouched. Thanks! – gtamborero Feb 19 '22 at 14:55
130

To search an element in an array, you can use array_search function and to remove an element from an array you can use unset function. Ex:

<?php
$hackers = array ('Alan Kay', 'Peter Norvig', 'Linus Trovalds', 'Larry Page');

print_r($hackers);

// Search
$pos = array_search('Linus Trovalds', $hackers);

// array_seearch returns false if an element is not found
// so we need to do a strict check here to make sure
if ($pos !== false) {
    echo 'Linus Trovalds found at: ' . $pos;

    // Remove from array
    unset($hackers[$pos]);
}

print_r($hackers);

You can refer: https://www.php.net/manual/en/ref.array.php for more array related functions.

Cave Johnson
  • 6,499
  • 5
  • 38
  • 57
mohitsoni
  • 3,091
  • 3
  • 19
  • 10
  • What if there is no exact match? how to perform a wildcard search? – Clain Dsilva Nov 12 '14 at 02:26
  • 3
    Also note that `unset()` will turn the array into an associative array. To turn it back into an array (without keys) use [`array_values()`](http://php.net/manual/en/function.array-values.php) – Jespertheend Aug 03 '16 at 21:36
  • To search by the value of a key you can combine this with `array_column`, ie: `$pos = array_search(1234, array_column('id', $dataset));` – Geoffrey Jan 01 '17 at 03:41
19

You need to find the key of the array first, this can be done using array_search()

Once done, use the unset()

<?php
$array = array( 'apple', 'orange', 'pear' );

unset( $array[array_search( 'orange', $array )] );
?>
Gordon
  • 312,688
  • 75
  • 539
  • 559
Kerry Jones
  • 21,806
  • 12
  • 62
  • 89
  • This is the result Array ( [0] => apple [1] => orange [2] => pear [3] => green ) Warning: Wrong parameter count for array_search() in C:\wamp\www\test\test.php on line 5 Array ( [0] => apple [1] => orange [2] => pear [3] => green ) – DEVOPS Jun 17 '10 at 06:43
  • 2
    @learner the haystack argument was missing in http://de3.php.net/manual/en/function.array-search.php - the manual is your friend. – Gordon Jun 17 '10 at 06:45
  • yes. this will work $array = array( 'apple', 'orange', 'pear', 'green' ); unset($array[array_search('orange', $array)]); but the array sequence is missing. How to correct that – DEVOPS Jun 17 '10 at 06:49
  • What do you mean the sequence is missing? What sequence should it be in? – Kerry Jones Jun 17 '10 at 06:53
  • array index is 0 2 3 4 is now 1 is missing I need it like 0 1 2 4.. etc – DEVOPS Jun 17 '10 at 06:54
  • also it has one another pbm if the search value not there array_search() function return false. it will cause the removal of 0th index value :( – DEVOPS Jun 17 '10 at 06:56
  • Then test the value before you remove it `$key = array_search( 'value' );` And not to take the credit, but to reindex arrays, see here: http://stackoverflow.com/questions/591094/how-do-you-reindex-an-array-in-php – Kerry Jones Jun 17 '10 at 07:02
  • But if array_search returns false because of nothing found, the first array value will be removed. – algorhythm Sep 08 '14 at 15:26
  • ^ I haven't verified that, but if it is true, simply do an `if ( isset( ... ) ) ` before it – Kerry Jones Sep 08 '14 at 18:23
10

Just in case you want to use any of mentioned codes, be aware that array_search returns FALSE when the "needle" is not found in "haystack" and therefore these samples would unset the first (zero-indexed) item. Use this instead:

<?php
$haystack = Array('one', 'two', 'three');
if (($key = array_search('four', $haystack)) !== FALSE) {
  unset($haystack[$key]);
}
var_dump($haystack);

The above example will output:

Array
(
    [0] => one
    [1] => two
    [2] => three
)

And that's good!

chyno
  • 382
  • 3
  • 13
7

You can use array_filter to filter out elements of an array based on a callback function. The callback function takes each element of the array as an argument and you simply return false if that element should be removed. This also has the benefit of removing duplicate values since it scans the entire array.

You can use it like this:

$myArray = array('apple', 'orange', 'banana', 'plum', 'banana');
$output = array_filter($myArray, function($value) { return $value !== 'banana'; });
// content of $output after previous line:
// $output = array('apple', 'orange', 'plum');

And if you want to re-index the array, you can pass the result to array_values like this:

$output = array_values($output);
Cave Johnson
  • 6,499
  • 5
  • 38
  • 57
4

This solution is the combination of @Peter's solution for deleting multiple occurences and @chyno solution for removing first occurence. That's it what I'm using.

/**
 * @param array $haystack
 * @param mixed $value
 * @param bool $only_first
 * @return array
 */
function array_remove_values(array $haystack, $needle = null, $only_first = false)
{
    if (!is_bool($only_first)) { throw new Exception("The parameter 'only_first' must have type boolean."); }
    if (empty($haystack)) { return $haystack; }

    if ($only_first) { // remove the first found value
        if (($pos = array_search($needle, $haystack)) !== false) {
            unset($haystack[$pos]);
        }
    } else { // remove all occurences of 'needle'
        $haystack = array_diff($haystack, array($needle));
    }

    return $haystack;
}

Also have a look here: PHP array delete by value (not key)

Community
  • 1
  • 1
algorhythm
  • 8,530
  • 3
  • 35
  • 47
2

The unset array_search has some pretty terrible side effects because it can accidentally strip the first element off your array regardless of the value:

        // bad side effects
        $a = [0,1,2,3,4,5];
        unset($a[array_search(3, $a)]);
        unset($a[array_search(6, $a)]);
        $this->log_json($a);
        // result: [1,2,4,5]
        // what? where is 0?
        // it was removed because false is interpreted as 0

        // goodness
        $b = [0,1,2,3,4,5];
        $b = array_diff($b, [3,6]);
        $this->log_json($b);
        // result: [0,1,2,4,5]

If you know that the value is guaranteed to be in the array, go for it, but I think the array_diff is far safer. (I'm using php7)

  • Only if you don't do a strict comparison for `false`. Algorhythm's and chyno's answers many years earlier do not make this mistake. – mickmackusa Jan 22 '22 at 04:19
2
$data_arr = array('hello', 'developer', 'laravel' );


// We Have to remove Value "hello" from the array
// Check if the value is exists in the array

if (array_search('hello', $data_arr ) !== false) {
     
     $key = array_search('hello', $data_arr );
     
     unset( $data_arr[$key] );
}



# output:
// It will Return unsorted Indexed array
print( $data_arr )


// To Sort Array index use this
$data_arr = array_values( $data_arr );


// Now the array key is sorted
Chandan Sharma
  • 2,321
  • 22
  • 22
1

First of all, as others mentioned, you will be using the "array_search()" & the "unset()" methodsas shown below:-

<?php
$arrayDummy = array( 'aaaa', 'bbbb', 'cccc', 'dddd', 'eeee', 'ffff', 'gggg' );
unset( $arrayDummy[array_search( 'dddd', $arrayDummy )] ); // Index 3 is getting unset here.
print_r( $arrayDummy ); // This will show the indexes as 0, 1, 2, 4, 5, 6.
?>

Now to re-index the same array, without sorting any of the array values, you will need to use the "array_values()" method as shown below:-

<?php
$arrayDummy = array_values( $arrayDummy );
print_r( $arrayDummy ); // Now, you will see the indexes as 0, 1, 2, 3, 4, 5.
?>

Hope it helps.

Knowledge Craving
  • 7,955
  • 13
  • 49
  • 92
  • 2
    But if array_search returns false because of nothing found, the first array value will be removed. – algorhythm Sep 08 '14 at 15:23
  • @algorhythm - Thanks for pointing that out! I will suggest that everyone should use the solution provided by you! – Knowledge Craving Sep 08 '14 at 17:48
  • When you know that an answer is flawed and you leave ot on the page anyhow, you are only damaging the Researcher eXperience by confusing them with bad advice and/or wasting their time. – mickmackusa Jan 22 '22 at 04:18
0

Okay, this is a bit longer, but does a couple of cool things.

I was trying to filter a list of emails but exclude certain domains and emails.

Script below will...

  1. Remove any records with a certain domain
  2. Remove any email with an exact value.

First you need an array with a list of emails and then you can add certain domains or individual email accounts to exclusion lists.

Then it will output a list of clean records at the end.

//list of domains to exclude
$excluded_domains = array(
    "domain1.com",
);

//list of emails to exclude
$excluded_emails = array(
    "bob@domain2.com",
    "joe@domain3.com",    
);

function get_domain($email) {

    $domain = explode("@", $email);
    $domain = $domain[1];
    return $domain;

}

//loop through list of emails
foreach($emails as $email) {

    //set false flag
    $exclude = false;

    //extract the domain from the email     
    $domain = get_domain($email);

    //check if the domain is in the exclude domains list
    if(in_array($domain, $excluded_domains)){
        $exclude = true;
    }

    //check if the domain is in the exclude emails list
    if(in_array($email, $excluded_emails)){
        $exclude = true;
    } 

    //if its not excluded add it to the final array
    if($exclude == false) {
        $clean_email_list[] = $email;
    }

    $count = $count + 1;
}

print_r($clean_email_list);
Craig Edmonds
  • 2,052
  • 3
  • 14
  • 13
-1

To find and remove multiple instance of value in an array, i have used the below code

$list = array(1,3,4,1,3,1,5,8);

$new_arr=array();

foreach($list as $value){

    if($value=='1')
    {
        continue;
    }
    else
    {
        $new_arr[]=$value;
    }     
}


print_r($new_arr);
Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992