1

Appreciate your time!

After reviewing several 'Compare and Merge' threads, finally, I am going to request someone to help with this very specific scenario.

$input = array(
  [ 2616 ] => array(
    [ 9878767654 ] => array(
      [ 987987987 ] => 987987987, 
      [ 987987986 ] => 987987986,
    ),
  ), 
  [ 2618 ] => array(
    [ 9878767654 ] => array(
      [ 987987987 ] => 987987987,
    ),

  ), 
  [ 'tmp-9878767654' ] => array(
    [ 9878767654 ] => array(
      [ 987987985 ] => 987987985, 
      [ 987987987 ] => 987987987,
    ),

  ), 
  [ 'tmp-9878767655' ] => array(
    [ 9878767655 ] => array(
      [ 987987975 ] => 987987975,
    ),
  ),
);

$desired_output = array(
  [ 2616 ] => array(
    [ 9878767654 ] => array(
      [ 987987987 ] => 987987987, 
      [ 987987986 ] => 987987986,
      [ 987987985 ] => 987987985,
    ),
  ),
  [ 2618 ] => array(
    [ 9878767654 ] => array(
      [ 987987987 ] => 987987987, 
      [ 987987986 ] => 987987986,
      [ 987987985 ] => 987987985,
    ),
  ),
  [ 'tmp-9878767655' ] => array(
    [ 9878767655 ] => array(
      [ 987987975 ] => 987987975,
    ),
  ),
);

This is the inventory of products (listed by Product ID and Model ID) by Store ID. I want to merge the Model ID values WHERE the product id is the same FROM the array with store-ID starting with 'tmp-'. If product ID is not matched then I want that array to stay as it is. I hope I am making some sense.

Please help.

1 Answer 1

1

Here is a snippet to solve the specific problem posed by your example:

$temporaryStores = [];
$prefix = 'tmp-';
$prefixLength = strlen($prefix);

// extract the temporary store structures
foreach ($input as $storeId => $store) {
    if (is_string($storeId) && strpos($storeId, $prefix) === 0) {
        $productId = (int) substr($storeId, $prefixLength);
        $temporaryStores[$productId] = $store;
        unset($input[$storeId]);
    }
}

// merge matching temporary store structures into the actual ones
$mergedProductIds = [];
foreach ($temporaryStores as $temporaryProductId => $temporaryModels) {
    $temporaryModels = reset($temporaryModels); // Incompatible array structure
    foreach ($input as $storeId => $store) {
        foreach ($store as $productId => $models) {
            if ($productId === $temporaryProductId) {
                $modelsIds = array_merge($temporaryModels, $models);
                $modelsIds = array_unique($modelsIds);
                $input[$storeId][$productId] = $modelsIds;
                $mergedProductIds[] = $temporaryProductId;
                unset($temporaryStores[$temporaryProductId]);
            }
        }
    }
}

// append leftover temporary store structures to the result
foreach ($temporaryStores as $temporaryProductId => $temporaryModels) {
    if (!in_array($temporaryProductId, $mergedProductIds, true)) {
        $input[$prefix . $temporaryProductId] = $temporaryModels;
    }
}

var_dump($input);

This snippet might work for you or not. Either way, I strongly suggest you refactor this code into using a more object oriented design. Where it is made obvious what each value/structure represents, and validation can occur in isolation.

Now you are left having to deal with incompatible array structures that visually look like an incomprehensible mess.

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

3 Comments

Thank you so much, I will give it a try. I agree with you on your comment. This data is coming from queries from multiple databases and the structures are slightly different from each other. The other factor is that a store wants to detect if there are duplicate products as well. Appreciate your help.
Almost there, it skipped the merger for the second store ID which had a duplicate product id. I will have to rethink this entire function I guess, there are going to be thousands of products, and running three different for each loop will kill the performance.
I guess you can add (yet another) exception to this logic. But I hope you find a way to restructure this code into a more logical (and easier to work with) OOP solution. Good luck!

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.