简体   繁体   中英

How to detect a cycle in an multidimensional array of elements php

I'm not sure how to implement this but I will explain my problem. I have an array of products those products have a product id as well as a parent product id. So something like this

productsArray{
productID = 624
name = PS4
...
parentProductID = 5388
}

What I need help with is how to check if a products parent has already been visited which I am assuming would find a cycle and if there isn't a cycle I would like to add that item into an array. But I'm not sure how to exactly go about doing this.

Setting up a simple product list.

$productsArray = [
    [
        'productID'       => 624,
        'name'            => 'PS4',
        'parentProductID' => 5388,
    ],
    [
        'productID'       => 123,
        'name'            => 'PS5',
        'parentProductID' => 7896,
    ],
];

Now, we create the visited list.

Cast the ID to a string, to prevent a numeric indexed array, because they start at 0. Put the ID into visited[] as key and the count as value. If key is not there, start with 1 otherwise increment.

$visited = [];
foreach ($productsArray as $product) {
    foreach ($product as $key => $id) {
        if (in_array($key, ['productID', 'parentProductID'])) {
            $id           = (string) $id;
            $visited[$id] = isset($visited[$id]) ? $visited[$id]++ : 1;
        }
    }
}

Now, let's have a product and verify it was already visited. If yes, do not add. This example is in the visited list, so we won't add it as a duplicate.

$newProduct = [
    'productID'       => 123,
    'name'            => 'PS5',
    'parentProductID' => 7896,
];

addToProducts($visited, $productsArray, $newProduct);

function addToProducts(array &$visited, array &$productsArray, array $newProduct): void
{
    // Get IDs as string
    $id1 = isset($newProduct['productID'])       ? (string) $newProduct['productID']       : '';
    $id2 = isset($newProduct['parentProductID']) ? (string) $newProduct['parentProductID'] : '';
    
    // Any ID is already visited, then return
    if(isset($visited[$id1]) || isset($visited[$id2])) {
        return;
    }
    
    // Put IDs into visited
    $visited[$id1] = isset($visited[$id1]) ? $visited[$id1]++ : 1;
    $visited[$id2] = isset($visited[$id2]) ? $visited[$id2]++ : 1;

    // Add Product
    $productsArray[] = $newProduct;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM