0

I have an array in an array in an array. How can I search if any of these arrays have a specific key and value? If not remove this array from array.

Example:

array:3 [▼
  0 => array:2 [▼
    "location" => array:4 [▶]
    "promotions" => array:1 [▶]
  ]
  1 => array:2 [▼
    "city" => array:4 [▶]
    "promotions" => array:2 [▼
      0 => array:5 [▶]
      1 => array:5 [▼
        "distance" => "0.2288511878121104"
        "promoid" => 54
        "promo" => Promotion {#1259 ▶}
        "product" => Products {#1162 ▶}
        "productID" => 5
      ]
    ]
  ]
  2 => array:2 [▼
    "city" => array:4 [▶]
    "promotions" => []
  ]
]

I want to search "productID" with value 5, and I want to remove array in promotions which doesn`t have this value.


SOLVED

    foreach ($locations as $key => $location) {
        foreach ($location['promotions'] as $item => $promotions) {
            if (is_array($promotions)) {
                foreach ($promotions as $k => $value) {
                    if (!is_array($value)) {
                        if ($k == 'productID' && $value != $id) {
                            unset($locations[$key]['promotions'][$item]);

                        }
                    }
                }
            }
        }
    }
Jason Aller
  • 3,541
  • 28
  • 38
  • 38
flow
  • 127
  • 2
  • 14
  • Loops + [in_array()](https://www.php.net/manual/en/function.in-array.php) + [deleting an element from an array in PHP](https://stackoverflow.com/questions/369602/deleting-an-element-from-an-array-in-php?rq=1) – Juan Eizmendi Jul 24 '21 at 02:29
  • Yes, ok. But how to use in_array() with key aswell? how to find "productID":"5" – flow Jul 24 '21 at 02:39
  • my bad didn't see the key, you can check for the key with [array_key_exists()](https://www.php.net/manual/en/function.array-key-exists.php) or with `isset($arr[$key])` – Juan Eizmendi Jul 24 '21 at 02:43
  • yea i know, but how to check promotions array if got both together, as key->value if exist unset whole upper array, that i understand. But how to do example find key foo with value boo – flow Jul 24 '21 at 03:03
  • ok i solved, i edited my question. Thanks for show me the doors :) – flow Jul 24 '21 at 03:14

2 Answers2

2

You could use a recursive function and unset() the target

<?php
// example code

$a = [
    'test' => 'foo',
    'bar' => [
        'productID' => 5,
        'something' => 'else'
        ],
        'bar2' => [
        'productID' => 6,
        'something2' => 'else'
        ]
    ];
    
    function removeItem($array, $search) {
        $s = explode(":",$search);
        $skey = trim($s[0]);
        $sval = trim($s[1]);
        foreach ($array as $n => $v) {
            if ($n == $skey && $v == $sval) {
                unset($array[$n]);
            } else {
                if (is_array($v)) $v = removeItem($v, $search);
                $array[$n]  = $v;
            }
        }
        return $array;
    
    }
    $a = removeItem($a, 'productID:5');
    print_r($a);
    

example: https://www.tehplayground.com/zJ2bKplP1pDaV8Ss

Kinglish
  • 23,358
  • 3
  • 22
  • 43
1

Nice solve, you can skip the 3er loop, checking if the key is set with isset()

foreach ($arr as $key => $location) {
    if (!is_array($location)) { //if child is not an array ignore it
        continue;
    }

    foreach ($location as $item => $promotions) {
        if (!is_array($location)) {//if child is not an array ignore it
            continue;
        }

        if (
            isset($promotions['productID']) && //3er lvl, Has the key?
            $promotions['productID'] == $id //Has the id
        ) {
            continue; //This is a match so, ignore it
        } else {
            unset($arr[$key][$item]); //This promotion doesn't have it.
        }
    }
}

And this one checks at all levels, it uses recursive fn

$ans = deepClean($arr, 'productID', 5);
function deepClean($arr, $search_key, $search_value): ?array
{
    if (
        isset($arr[$search_key]) &&  //Has the key
        $arr[$search_key] == $search_value  //Match value
    ) {
        return $arr;
    }

    //check children
    $currentLevel = [];
    foreach ($arr as $key => $value) {
        if (!is_array($value)) {
            continue;
        }

        $deepArr = deepClean($value, $search_key, $search_value);
        if (is_array($deepArr)) { //child has search?
            $currentLevel[$key] = $deepArr;
        }
    }

    return $currentLevel === [] ? null : $currentLevel;
}
Juan Eizmendi
  • 984
  • 6
  • 10