-1

I have two arrays:

$array1 = [
    'user_id' => '1234567890', 
    'customer_id' => [
        '889599494514048876' => [admin => true],
        '006994743818411627' => [admin => false],
        '259960192293339276' => [admin => false]
    ]
];
$array2 = [
    'customer_id' => [
        '259960192293339276' => [admin => false]
    ]
];

I want to check if array2 exists in array1.

"Ideally" the solution would be dynamic, so no matter how nested or different the array structure is, it would still work. Any solution or ideas are still much appreciated though, as I'm quite stuck.

I've looked at array_intersect and array_uintersect, though I haven't gotten them to work like I would have wanted.

David
  • 99
  • 6
  • You're asking for something far too broad: "no matter how nested or different the array structure is". You need to narrow your problem down to something that can reasonably be answered. It's not even clear what the correct result is for the sample data you have provided - on a literal basis the answer would be false (`$array2` does not exist in `$array1`) but `$array2` is a subset of `$array1` (`$array1` can be constructed starting with `$array2` and just adding elements) so maybe the answer should be true? – Nick Nov 03 '20 at 22:30
  • To quote myself, I said "Ideally", and I know it's a broad thing to state, yet Chris managed to figure out a solution that work no matter how nested it is. I didn't think of using a recursive function, which is most likely the most neat solution in this case. – David Nov 04 '20 at 08:58

1 Answers1

0

You can just use a simple recursive function.

For the given data:

$array1 = [
    'user_id' => '1234567890',
    'customer_id' => [
        '889599494514048876' => ['admin' => true],
        '006994743818411627' => ['admin' => false],
        '259960192293339276' => ['admin' => false]
    ]
];

$array2 = [
    'customer_id' => [
        '259960192293339276' => ['admin' => false]
    ]
];

This function should work, see the code comments:

function isArraySubSetOfOtherArray(array $childArray, array $potentialParent): bool
{
    foreach ($childArray as $key => $value) {

        // If the other array doesn't have this key, fail
        if (!array_key_exists($key, $potentialParent)) {
            return false;
        }

        // Make sure the values are the same type, otherwise fail
        if (gettype($value) !== gettype($potentialParent[$key])) {
            return false;
        }

        // For scalar types, test them directly
        if (is_scalar($value)) {
            if ($value !== $potentialParent[$key]) {
                return false;
            }
            continue;
        }

        // For array, recurse into this same function
        if (is_array($value)) {
            if (!isArraySubSetOfOtherArray($value, $potentialParent[$key])) {
                return false;
            }
            continue;
        }

        // For anything else, fail or write some other logic
        throw new RuntimeException('Unsupported type');
    }

    // The loop passed without return false, so it is a subset
    return true;
}
assert(isArraySubSetOfOtherArray($array2, $array1));
Chris Haas
  • 53,986
  • 12
  • 141
  • 274