5

I have this array:

$array = [
    ['b', 'd', 'c', 'a', ''],
    ['c', 'a', 'd', '', ''],
    ['b', 'd', 'a', '', ''],
    ['c', 'd', 'a', 'b', '']
];

and need to delete (unset?) all elements where value is "c" so that one ends up with:

$array = [
    ['b', 'd', 'a', ''],
    ['a', 'd', '', ''],
    ['b', 'd', 'a', '', ''],
    ['d', 'a', 'b', '']
];

The element gets removed, and the other elements to shift up. I know that unset does not re-index the array. Cannot get to unset for all multidimensional arrays, but only with one array. Can the arrays be re-indexed afterwards?

The code BELOW removes elements where the value is equal to "c" but the index of the first element is not re-indexed. Can anyone suggest a solution to re-indexing the inner arrays?

$i = 0;
foreach ($array as $val)
{
    foreach ($val as $key => $final_val)
    {
        if ($final_val == "$search_value") 
        {
             unset($array[$i][$key]);
        }
    } 
    $i = $i + 1;
}
2
  • What do you expect the dimensions of the array to be afterwards? In general it will not be a rectangle. You probably need to look at the concept of sparse arrays if you really care that these are 2D, and that some elements are "once" (although even in sparse arrays "gone" really just means "zero"). Could you not set them to NaN instead? What are you really after?... Commented Jan 21, 2014 at 4:14
  • Floris - not sure what you mean by that. I am looking for a simple removal of any elements where it has a certain value. Commented Jan 21, 2014 at 5:15

3 Answers 3

5

The following code will do what you want:

<?php
$a = 1;
$b = 2;
$c = 3;
$d = 4;

$arr = array(
array ( $b, $d, $c, $a, $b),
array ($c, $a),
array ( $b, $d,  $c ),
array( $c, $d, $a, $b, $b)
);
echo "before:\n";
print_r($arr);

foreach($arr as $k1=>$q) {
  foreach($q as $k2=>$r) {
    if($r == $c) {
      unset($arr[$k1][$k2]);
    }
  }
}
echo "after:\n";
print_r($arr);
?>

Output:

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

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

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

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

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

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

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

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

)

As you can see, all the 3's have gone...

Sign up to request clarification or add additional context in comments.

3 Comments

This answer clearly does not reindex the first row as required by the asker.
@mickmackusa - if you look at the comments under the question, you can see that "reindexing" is NOT actually what he wants. "I am looking for a simple removal of any elements where it has a certain value". If this didn't do what he wanted, he wouldn't have accepted the answer, I suppose.
I see that comment as an incomplete summary of the asked question. The body of the question mentions multiple times that re-indexing is desired.
0

Search the value in the sub array then unset it.

$search = 'c';
$result = array_map(function ($value) use ($search) {
   if(($key = array_search($search, $value)) !== false) {
      unset($value[$key]);
   }
   return $value;
}, $your_array);

Or you could use a loop too:

// this way change your original array
foreach ($your_array as &$sub_array) {
    if(($key = array_search($search, $sub_array)) !== false) {
        unset($sub_array[$key]);
    }
}
var_dump($your_array);

1 Comment

This answer will remove a maximum of one element per row and does not attempt to reindex the rows after mutating them.
0

For a sleek functional approach, use array_map() to access the rows, then use array_filter() or array_diff() to remove all elements with the value of c. array_filter() might perform slightly better than array_diff(), but array_diff() is less verbose and can be very easily adjusted to remove multiple blacklisted values.

array_search() will not be suitable if the sought value occurs more than once in a given row -- it will only return the key of the first match.

Before returning the mutated row, re-index it with array_values().

Code (Demo)

var_export(
    array_map(
        fn($row) => array_values(array_diff($row, ['c'])),
        $array
    )
);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.