Jump to content

Looping on API call with different arguments to push or update against array


thenorman138

Recommended Posts

I have code where I'm simply calling an API and I've converted it to loop the call so that I can call it with three different argument values. This is because the API is structured where it can accept one value for that argument at a time, but I need to compare the results of the three calls and I think the best way is to build a single array from the responses by either pushing a value if it exists or pushing the whole index if not. Think of it like the API response can give me data that can be as much as 400 products that are sold across 3 stores. All 400 may be sold in one store, but maybe only 120 in another and 100 in the third.

I need my array to be all 400 products but I'll want to have an array within that holds the stores for the  given product.

Code:


 

      $IdentifierTest = 1472;
        $arguments = ['store 1', 'store 2', 'store 3'];
        
        $TestApi = app(TestApi::class);
        $newArray = array();

        foreach($arguments as $argument){
            $testResponse = $TestApi->getData($IdentifierTest, $argument);
            $Data = $testResponse->getResult()->getData(); // get the final results of call
            
            //check if array empty, and if so, push all records
            // if not empty, start checking 'id' against existing array records. If match, push stores. If not, add record to array
        }
        

        $this->makeFile($IdentifierTest, $Data);

An example of the response is:

        array:426 [▼
            0 => prices {#2698 ▼
                #container: array:11 [▼
                        "prd" => 2380
                        "id" => "173489"
                        "price" => "65.00"
                ]
            }

The issue is that specific example only shows up when calling the API with 'store 1' and 'store 2' as the argument, but not 'store 3'. What I'd like to do is call the API with each argument and create a new array with a ```stores``` index that pushes the store number if the id exists in the call, like so:

        array:426 [▼
            0 => prices {#2698 ▼
                #container: array:11 [▼
                        "prd" => 2380
                        "id" => "173489"
                        "price" => "65.00"
                        stores: array[
                           'store 1',
                           'store 2'     
                        ]
                ]
            }

So when it's called with 'store 1' I would push the response into an array with 'store 1' as the value in 'stores', then on 'store 2' I would take the response and first check to see if the id exists in the array I've made. If it exists, I'll  add 'store 2' to the 'stores' and if not I'll make a new index in the array.

Basically, if product (id) 178293 is sold in all three stores then that means it would come back in all 3 API response calls and would end up being a single record in this new array with ```stores['store 1', 'store 2', 'store 3']```

How can I create a new array from this where I push only the stores if the id exists in the API call while keeping the current structure? 

Edited by thenorman138
Link to comment
Share on other sites

1. You need an array to put all the data you're receiving. $newArray isn't the greatest name but it'll work for the moment.
2. For each price item you receive from the API, check if you have it in that array already: if so then update its list of stores, otherwise add it.

It looks like $Data is: an array of prices, where each price is a "prices" object, and that object has a private "container" array of the data. The problem here is that you can't (nor, in fact, should) add anything to that container array: it pollutes the concept of the "prices" object with data it doesn't know about.

In your shoes, I think I would change the above approach to be: you have two arrays, one of all the prices with no store data, and another that tells you which prices are in which store.
The new approach is:

1. You need the one array for all the data - let's say "$allPrices". You need a second array just to associate prices with stores - let's say "$pricesToStores".
2. For each price item you receive from the API, add it to $allPrices. Because there will be duplicates, don't add it blindly but instead index the array by the unique identifier; that'll be either the "prd" or the "id", I can't tell.
3. At the same time, add information to $pricesToStores for the price item and the store. They should be indexed by the prd/id as well, and the array values can be the set of stores it was found in.

There's probably a small issue though: when two stores have the same item, is the data for those two items exactly the same? I think not. My guess is that the "prd" will be the same but the "id" will not (or vice versa). If you simply keep one of the prices in $allPrices then you lose what the other ones were, so perhaps you might need to retain all the prices together in a sub-array. But if you have to do that, does the price data mention which store it came from already? Because if it does then the $pricesToStores array is pointless.

So after all that, a question: what does the price data look like for 2+ stores that have the "same" one?

  • Like 1
Link to comment
Share on other sites

Thanks for all the great points there. 

To answer the biggest question: yes, if a product belongs to 3 stores the data is all the same. Price, prd, id, all of it is exactly the same; it's just a matter of how many stores are 'allowed' to sell the product. So all this eventual spreadsheet will do is give me a list of these products and their assigned prices along with any stores where they could be available. 

The last example in my question is the closest thing to a real world version of 2 stores having the same product: product and price data is identical, there's just a subarray showing stores

Link to comment
Share on other sites

Then that makes it a little easier. Figure out which of prid and id is the unique identifier - they probably aren't both equally unique because then why would there be two of them? - and use that for your array keys.

You end up with arrays that look like

$allPrices = [
	// picking id,
	173489 => prices { #2698
		#container...
	}
];

$pricesToStores = [
	173489 => [
		'store 1',
		'store 2'
	]
];

That keeps the prices objects in one place, and using the prid/id as the keys in both places means you can easily look up which stores any one is associated with.

Link to comment
Share on other sites

I appreciate the response, and the unique identifier is indeed 'prd'. The issue is that I really need a single array, with stores as sub-array, as this is going straight into a spreadsheet builder and looping through each record (each store being it's own column with either the price or 'none' if no match on store).

I was thinking of rather than pushing where I am, just looping on each record in the array and checking to see if 'prd' exists yet: If so, I'll push the store name into the sub-array of $newArray, and if not I'll add the whole record.

My issue there is that I was going to use If(array_key_exists) but I don't think that's the right approach here as I need to explicitly state what the 'key' is for the check

Edited by thenorman138
Link to comment
Share on other sites

If you need a single array then you'll have to do away with the prices objects and re-bundle their data into arrays.

array(
	0 => array(
		"prd" => 2380,
		"id" => "173489",
		"price" => "65.00",
		"stores" => array(
			"store 1",
			"store 2"
		)
	)
)

Unless your spreadsheet builder thing is a pain, you could take that 0 => array and re-key it to the prd as 2380 => array. Similar to before, you can then use the prd every time to insert-or-update into this larger array: insert when there is no existing [2380] yet, update with array[2380]["stores"][] = "store 2" when it does exist.

  • Like 1
Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.