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

                        }
                    }
                }
            }
        }
    }
5
  • Loops + in_array() + deleting an element from an array in PHP Commented Jul 24, 2021 at 2:29
  • Yes, ok. But how to use in_array() with key aswell? how to find "productID":"5" Commented Jul 24, 2021 at 2:39
  • my bad didn't see the key, you can check for the key with array_key_exists() or with isset($arr[$key]) Commented Jul 24, 2021 at 2: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 Commented Jul 24, 2021 at 3:03
  • ok i solved, i edited my question. Thanks for show me the doors :) Commented Jul 24, 2021 at 3:14

2 Answers 2

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

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

Comments

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

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.