I'm trying to create an unknown number of arrays dynamically inside a foreach loop, merge them all at the end into one array, and use this in a JSON format for Google Analytics.
So far I have the following code which is throwing an error at the merge part:
$p=1;
foreach(...){
...
$arr = 'arr'.$p;
$name = $order->ProductGroupName;
$name = str_replace("'", "", $name);
$arr = array(
"name"=>$name,
"id"=>$order->ProductCode,
"price"=>$order->RRP,
"quantity"=>$order->Quantity
);
$p++;
}
for ($q = 1; $q<$p; $q++){
$arry = 'arr'.$q;
$merge = array_merge($arry, $merge);
};
How do I create the arrays dynamically and merge them at the end, please?
I'm relatively new to PHP and have tried my best to get this to work.
I think I understand what you're trying to do. Just dynamically append [] to the array and you don't need to merge:
foreach($something as $order) {
$arr[] = array (
"name"=>str_replace("'", "", $order->ProductGroupName),
"id"=>$order->ProductCode,
"price"=>$order->RRP,
"quantity"=>$order->Quantity
);
}
If you want to have string keys for whatever reason, then:
$p = 1;
foreach($something as $order) {
$arr["SomeText$p"] = array (
"name"=>str_replace("'", "", $order->ProductGroupName),
"id"=>$order->ProductCode,
"price"=>$order->RRP,
"quantity"=>$order->Quantity
);
$p++;
}
And that's it. Check with:
print_r($arr);
Things like $arry = 'arr'.$q; stink of variable variables (though not done correctly) and shouldn't be used.
Related
I'm super new at php, I'm working on a game in Unity c# and I'm trying to send and receive data from a mysql server. I think I'm having a problem with syntax. I basically have a string that's being sent from my c# script that holds multiple ships with their stats. The ships are seperated by zzz which is a string of it's stats separated by space. I'd like to be able to set the stats array within the ships array. This is what I have but it's not working. Thanks!!
$shiparraytobesplit = $_POST["shipinventory"];
$ships = explode("zzz", $shiparraytobesplit);
for($i = 0; $i<count($ships)-1; $i++)
{
$tempship[$i] = $ships[$i];
$tempshipinfo = explode(" ", $tempship);
for($ii = 0; $ii<count($tempshipinfo[!i])-1; $ii++)
{
//$shipinfo[$tempship][] = $info . '_' . $tempshipinfo;
$shipinfo[$ii] = $tempshipinfo[$ii];
}
echo $shipinfo[1];
}
I've tried a few variations but I can't seem to get it to work with this example. I'm probably missing something simple since I'm a total noob to php and kind of new to programming. Thanks again
You have some extraneous subscripts that aren't needed.
If you have an extra element in the array, it's probably easier to just unset it, then you can loop over the entire array. array_map() is an easy way to produce a new array from an existing array.
$shiparraytobesplit = $_POST["shipinventory"];
$ships = explode("zzz", $shiparraytobesplit);
unset($ships[count($ships)-1]);
$shipinfo = array_map(function($ship) {
$tempshipinfo = explode(" ", $ship);
unset($tempshipinfo[count($tempshipinfo)-1]);
return $tempshipinfo;
}, $ships);
print_r($shipinfo);
If you want associative arrays, you can do that in the function.
$shiparraytobesplit = $_POST["shipinventory"];
$ships = explode("zzz", $shiparraytobesplit);
unset($ships[count($ships)-1]);
$shipinfo = array_map(function($ship) {
$tempshipinfo = explode(" ", $ship);
$ship_assoc = [
"id" => $tempshipinfo[0],
"name" => $tempshipinfo[1],
"username" => $tempshipinfo[2],
"hp" => $tempshipinfo[3]
];
return $ship_assoc;
}, $ships);
print_r($shipinfo);
I am doing laravel project. I have one sql query as,
$catcount=2;
for($i=0;$i<$catcount;$i++) {
$subCat[] = Category::where('parent_id', '=', $userCategory[$i])->pluck('id');
}
$subCat returns an array as,
[[54,55,56,57,58],[48,49,50,51,52]]
I want this array as a single dimensional array like,
[54,55,56,57,58,48,49,50,51,52]
I am not getting how to do this, Please help and thanks in advance.
I suggest You to do ids merge before querying, so You will save some run time by accessing database only one time.
$catcount = 2;
$parents_ids = [];
for ($i = 0; $i < $catcount; $i++) {
$parents_ids[] = $userCategory[$i];
}
$subCats = Category::whereIn('parent_id', $parents_ids)->pluck('id');
$catcount=2;
for($i=0;$i<$catcount;$i++) {
$subCat[] = Category::where('parent_id', '=' $userCategory[$i])->pluck('id');
}
array_merge($subCat[0],$subCat[1]);
From your final array, you can just do an array merge
list($a1, $a2) = $subCat;
$subCat = array_merge($a1, $a2);
There are a lot of ways to do that. One of them: simple, but universal, readable and updatable (if something will change in your data structure, you'll be able to update this code in no time):
$newArr = [];
foreach ($subCat as $subArr) {
foreach ($subArr as $value) {
$newArr[] = $value;
}
}
if your array have multiple elements, you can merge them using this code:
$subCats = call_user_func_array("array_merge", $subCat);
If i knew the correct terms to search these would be easy to google this but im not sure on the terminology.
I have an API that returns a big object. There is one particular one i access via:
$bug->fields->customfield_10205[0]->name;
//result is johndoe#gmail.com
There is numerous values and i can access them by changing it from 0 to 1 and so on
But i want to loop through the array (maybe thats not the correct term) and get all the emails in there and add it to a string like this:
implode(',', $array);
//This is private code so not worried too much about escaping
Would have thought i just do something like:
echo implode(',', $bug->fields->customfield_10205->name);
Also tried
echo implode(',', $bug->fields->customfield_10205);
And
echo implode(',', $bug->fields->customfield_10205[]->name);
The output im looking for is:
'johndoe#gmail.com,marydoe#gmail.com,patdoe#gmail.com'
Where am i going wrong and i apologize in advance for the silly question, this is probably so newbie
You need an iteration, such as
# an array to store all the name attribute
$names = array();
foreach ($bug->fields->customfield_10205 as $idx=>$obj)
{
$names[] = $obj->name;
}
# then format it to whatever format your like
$str_names = implode(',', $names);
PS: You should look for attribute email instead of name, however, I just follow your code
use this code ,and loop through the array.
$arr = array();
for($i = 0; $i < count($bug->fields->customfield_10205); $i++)
{
$arr[] = $bug->fields->customfield_10205[$i]->name;
}
$arr = implode(','$arr);
This is not possible in PHP without using an additional loop and a temporary list:
$names = array();
foreach($bug->fields->customfield_10205 as $v)
{
$names[] = $v->name;
}
implode(',', $names);
You can use array_map function like this
function map($item)
{
return $item->fields->customfield_10205[0]->name;
}
implode(',', array_map("map", $bugs)); // the $bugs is the original array
pretty straight forward question this - I am trying to create an array to store the Model and Cost values taken from my database table. I figured I could begin the array, then create a while loop, and then end the array, and smiles all around. I may be mistaken, or I may have blindly missed something in my code, but could you have a look?
$array = array(
while ($overall_cost = mysql_fetch_assoc($query_ocost)) {
$overall_cost["model"] => $overall_cost["cost"],
}
);
var_dump($array);
I think this is what you're looking for:
$array = array();
while ($overall_cost = mysql_fetch_assoc($query_ocost)) {
$array[$overall_cost["model"]] = $overall_cost["cost"];
}
var_dump($array);
You can't do it like this. You need to add to the array inside the while loop:
$array = array();
while ($overall_cost = mysql_fetch_assoc($query_ocost)) {
$array[$overall_cost["model"]] = $overall_cost["cost"];
}
var_dump($array);
would be one way of doing it.
EDITED to produce simple array.
I don't think that will work. Try something like:
$array = array();
while ($overall_cost = mysql_fetch_assoc($query_ocost)) {
$array[$overall_cost["model"]] = $overall_cost["cost"];
}
var_dump($array);
I have a PHP array that I'd like to duplicate but only copy elements from the array whose keys appear in another array.
Here are my arrays:
$data[123] = 'aaa';
$data[423] = 'bbb';
$data[543] = 'ccc';
$data[231] = 'ddd';
$data[642] = 'eee';
$data[643] = 'fff';
$data[712] = 'ggg';
$data[777] = 'hhh';
$keys_to_copy[] = '123';
$keys_to_copy[] = '231';
$keys_to_copy[] = '643';
$keys_to_copy[] = '712';
$keys_to_copy[] = '777';
$copied_data[123] = 'aaa';
$copied_data[231] = 'ddd';
$copied_data[643] = 'fff';
$copied_data[712] = 'ggg';
$copied_data[777] = 'hhh';
I could just loop through the data array like this:
foreach ($data as $key => $value) {
if ( in_array($key, $keys_to_copy)) {
$copied_data[$key] = $value;
}
}
But this will be happening inside a loop which is retrieving data from a MySQL result set. So it would be a loop nested within a MySQL data loop.
I normally try and avoid nested loops unless there's no way of using PHP's built-in array functions to get the result I'm looking for.
But I'm also weary of having a nested loop within a MySQL data loop, I don't want to keep MySQL hanging around.
I'm probably worrying about nested loop performance unnecessarily as I'll never be doing this for more than a couple of hundred rows of data and maybe 10 keys.
But I'd like to know if there's a way of doing this with built-in PHP functions.
I had a look at array_intesect_key() but that doesn't quite do it, because my $keys_to_copy array has my desired keys as array values rather than keys.
Anyone got any ideas?
Cheers, B
I worked it out - I almost had it above.I thought I'd post the answer anyway for completeness. Hope this helps someone out!
array_intersect_key($data, array_flip($keys_to_copy))
Use array_flip() to switch $keys_to_copy so it can be used within array_intersect_keys()
I'll run some tests to compare performance between the manual loop above, to this answer. I would expect the built-in functions to be faster but they might be pretty equal. I know arrays are heavily optimised so I'm sure it will be close.
EDIT:
I have run some benchmarks using PHP CLI to compare the foreach() code in my question with the code in my answer above. The results are quite astounding.
Here's the code I used to benchmark, which I think is valid:
<?php
ini_set('max_execution_time', 0);//NOT NEEDED FOR CLI
// BUILD RANDOM DATA ARRAY
$data = array();
while ( count($data) <= 200000) {
$data[rand(0, 500000)] = rand(0, 500000);
}
$keys_to_copy = array_rand($data, 100000);
// FOREACH
$timer_start = microtime(TRUE);
foreach ($data as $key => $value) {
if ( in_array($key, $keys_to_copy)) {
$copied_data[$key] = $value;
}
}
echo 'foreach: '.(microtime(TRUE) - $timer_start)."s\r\n";
// BUILT-IN ARRAY FUNCTIONS
$timer_start = microtime(TRUE);
$copied_data = array_intersect_key($data, array_flip($keys_to_copy));
echo 'built-in: '.(microtime(TRUE) - $timer_start)."s\r\n";
?>
And the results...
foreach: 662.217s
array_intersect_key: 0.099s
So it's much faster over loads of array elements to use the PHP array functions rather than foreach. I thought it would be faster but not by that much!
Why not load the entire result set into an array, then begin processing with nested loops?
$query_result = mysql_query($my_query) or die(mysql_error());
$query_rows = mysql_num_rows($query_result);
for ($i = 0; $i < $query_rows; $i++)
{
$row = mysql_fetch_assoc($query_result);
// 'key' is the name of the column containing the data key (123)
// 'value' is the name of the column containing the value (aaa)
$data[$row['key']] = $row['value'];
}
foreach ($data as $key => $value)
{
if ( in_array($key, $keys_to_copy))
{
$copied_data[$key] = $value;
}
}