FartMachine4U
FartMachine4U

Reputation: 115

Remove row elements of a 2d array by value and reindex

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;
}

Upvotes: 5

Views: 16035

Answers (3)

mickmackusa
mickmackusa

Reputation: 48051

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
    )
);

Upvotes: 0

Floris
Floris

Reputation: 46435

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...

Upvotes: 5

xdazz
xdazz

Reputation: 160943

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);

Upvotes: 0

Related Questions