Search code examples
phparraysmultidimensional-arrayunset

Use one Array to filter result from another array, both are multidimensional


I pull one array from a data and one array from an API.

API Array (array1)

...
[71] => Array
        (
            [id] => integer
            [name] => example_name
            [logo] => url_of_image
            [lang] => en
        )
...

Database API (array2)

    ...
Array(
    [0] => integer
    [1] => integer
}
    ...

I want to use array2 to find any instances of the ID in array1, if they exist then unset the key.

Array diff doesn't work with multidimensional. There isn't a common key The values are dynamic so i can't hard code them Array filter won't take multi commands and doing a foreach results in an error

Notice: Array to string conversion in

PHP 5.6.

foreach($array2 as $key => $value) {
   foreach($array1 as $key1 => $value1) {
      if ($value1 == $value) {
         unset($arrat2[$key])
      }
   }
}

I had this buried somewhere to filter out languages i thought i could stick a foreach inside the function but that throws an array to string conversion.

$filtered = array();
                    $filtered = array_filter($array1, function($el) { return ($el['lang'] == "en"); });

Something like:

        $result = array();
            foreach($array2 as $value) {
                $result = array_filter($array1, function($ee) { return ($ee['id'] != $value); });
            }

Results in:

Notice: Undefined variable: value i

Var dumps array 2:

array(2) {
  [0]=>
  array(1) {
    ["id"]=>
    string(8) "random integer"
  }
  [1]=>
  array(1) {
    ["id"]=>
    string(9) "random integer"
  }
}

var dumps array 1:

array(151) {
  [0]=>
  array(4) {
    ["id"]=>
    int(integer 1)
    ["name"]=>
    string(7) "example name 1"
    ["logo"]=>
    string(97) "image1.png"
    ["lang"]=>
    string(2) "en"
  }
  [1]=>
  array(4) {
    ["id"]=>
    int(integer 2)
    ["name"]=>
    string(10) "example name 2"
    ["logo"]=>
    string(100) "image2.png"
    ["lang"]=>
    string(2) "en"
  }
  [2]=>
  array(4) {
    ["id"]=>
    int(integer 3)
    ["name"]=>
    string(9) "example name 3"
    ["logo"]=>
    string(99) "image3.png"
    ["lang"]=>
    string(2) "en"
  }

great answer, also had to make sure my two values were both integers being compared.


Solution

  • Depending on what you want to do, this might help (you can provide more than 1 filter per line in $array2, lines are OR'ed while multiple conditions in one line are AND'ed):

    <?php
    
    $array1 = array(
        array(
            "id" => 1,
            "name" => "foo",
            "logo" => "foo-logo.png",
            "lang" => "es"
        ),
        array(
            "id" => 3,
            "name" => "bar",
            "logo" => "bar-logo.png",
            "lang" => "en"
        ),
        array(
            "id" => 7,
            "name" => "xyz",
            "logo" => "xyz-logo.png",
            "lang" => "it"
        ),
        array(
            "id" => 15,
            "name" => "aaa",
            "logo" => "aaa-logo.png",
            "lang" => "it"
        ),
        array(
            "id" => 23,
            "name" => "aaa",
            "logo" => "aaa-logo.png",
            "lang" => "es"
        ),
    );
    
    // Filter out entries with id #7 OR lang = en OR (name = "aaa" AND lang = "es")
    $array2 = array(
        array("id" => 7),
        array("lang" => "en"),
        array("name" => "aaa", "lang" => "es")
    );
    
    echo "<pre>";
    
    $filtered = array_filter($array1, function($e) use ($array2)
    {
        foreach($array2 as $filters)
        {
            $doFilter = true;
            foreach($filters as $k => $v)
            {
                if (isset($e[$k]) && $e[$k] !== $v) {
                    $doFilter = false;
                    break;
                }
            }
            if ($doFilter)
            {
                return false;
            }
        }
        return true;
    });
    
    var_dump($filtered);
    

    Output:

    array(2) {
      [0]=>
      array(4) {
        ["id"]=>
        int(1)
        ["name"]=>
        string(3) "foo"
        ["logo"]=>
        string(12) "foo-logo.png"
        ["lang"]=>
        string(2) "es"
      }
      [3]=>
      array(4) {
        ["id"]=>
        int(15)
        ["name"]=>
        string(3) "aaa"
        ["logo"]=>
        string(12) "aaa-logo.png"
        ["lang"]=>
        string(2) "it"
      }
    }