skip to Main Content

I want to search values in array by key, but I am having trouble when those keys value are an array, I have the following code:

$key_to_search = "sizes";
$result   = [];
$array =  [
    "color" => "red",
    "subcolor" => "green",
    "sizes" => [
        "depth_mm" => 40.5,
        "width_mm" => 300,
        "height_mm" => 2
    ],
    "launch_date" => "2023-01-01"
];

$iterator = new RecursiveIteratorIterator(
    new RecursiveArrayIterator(
        $array
    )
); 

foreach($iterator as $key=>$value)
{
   if($key_to_search==$key && $value!=='')
   {
      $result[] = $value;
   }
}

var_dump($result);

The key to search is on $key_to_search variable, if I use other one which does not have an array as value its finding correctly the values, but when the value is an array it just ignored.

Expected result for search of "sizes" would be:

[
   "depth_mm" => 40.5,
   "width_mm" => 300,
   "height_mm" => 2
]

There’s a working example using the classic way without RecursiveIteratorIterator:

public function searchPropertyValuesByKey($key_to_search, $array_to_search = null) {
    if($array_to_search == null) {
       $array_to_search = [
        "color" => "red",
        "subcolor" => "green",
        "sizes" => [
            "depth_mm" => 40.5,
            "width_mm" => 300,
            "height_mm" => 2
        ],
        "launch_date" => "2023-01-01"
      ];
    }

    $result = [];
    foreach($array_to_search as $key=>$value)
    {
        if($key_to_search==$key && $value!=='')
        {
            $result[] = $value;
        }
        if(is_array($value)){
            $callback_result = $this->searchPropertyValuesByKey($key_to_search, $value);
            if($callback_result !== null) {
                $result[] = $callback_result;
            }
        }
    }
    if(count($result) == 1)
        return $result[0];
    else if(count($result) > 1)
        throw new Exception("Property '".$key_to_search."' is found multiple times! (".count($result).") ".json_encode($result).", in product_id: ".$this->id." >> ".json_encode($this->propierties)."");
    else
        return null;
}

2

Answers


  1. If you change the definition of $iterator to the following, it works as you’ve stated:

    $iterator = new RecursiveArrayIterator($data);
    

    I don’t believe that the RecursiveIteratorIterator is required.

    Login or Signup to reply.
  2. The constructor of RecursiveIteratorIterator has three parameters: a Traversable (which you correctly specified), a $mode, which defaults to RecursiveIteratorIterator::LEAVES_ONLY (that’s the problem) and $flags. So, in order to consider non-leaf items, you will need to specify a different value for your second parameter. I have tried your example with RecursiveIteratorIterator::SELF_FIRST and it worked.

    Code:

    $key_to_search = "sizes";
    $result   = [];
    $array =  [
        "color" => "red",
        "subcolor" => "green",
        "sizes" => [
            "depth_mm" => 40.5,
            "width_mm" => 300,
            "height_mm" => 2
        ],
        "launch_date" => "2023-01-01"
    ];
    
    $iterator = new RecursiveIteratorIterator(
        new RecursiveArrayIterator(
            $array
        ), RecursiveIteratorIterator::SELF_FIRST
    ); 
    
    foreach($iterator as $key=>$value)
    {
       if($key_to_search==$key && $value!=='')
       {
          $result[] = $value;
       }
    }
    
    var_dump($result);
    

    Result:

    enter image description here

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search