Simple variable assignment from two-dimensional array in php - php

I have a two-dimensional array with two key values, [program] and [balance], created by a MySQL SELECT statement in WordPress. I know what the values of [program] will be (they never change) - it's the balances I'm interested in.
For example:
*[program] = 'Sales', [balance] = 10,000*
*[program] = 'Commission', [balance] = 1,250*
All I want to do is assign the balance value to a variable, so I will have:
*$sales = (the balance for the Sales program)*
*$commission = (the balance for the Commission program)*
I know I'm being thick here, but I cannot see how to do this after about an hour of searching and screwing around with php. It's a total brain block and all the references I can find online talk about loops and echoing all the values and stuff.
Would appreciate a de-blocking!

//make a function
function findBalanceByProgram($inputArray,$program)
//loop trough all the keys on the first dimension
foreach($inputArray as $val){
//check in the second dimension if your program is the same as the program you are checking for
if($val['program']==$program)
//if so.. return the value and jump out of the function
return $val['balance'];
}
}
//an example of use.
echo findBalanceByProgram($yourArray,'sales');

Related

Assign random but even amount from an array to a list array in PHP?

I have two arrays. One array $People currently creates number of 44 individuals. Lets just assume currently its
$People = array('1','2',...,'44');.
I have another array of 15 elements.
$Test = array('A','B',...'O');
Now I want to be able to assign the test randomly to each individual. I know how to do this using random function in php.
Where it has got tricky for me and what I need help with is how can I even out the test array. What I mean by this is since there are currently 44 individuals (this array will grow in future), what I want is 14 test versions to have 3 individuals and 1 version would have 2. So I want the test array to even out. I also want it to handle as growth of $People array.
Ex: Test Version D will have individual '4', '25'. Every other version has three random individuals.
Few ideas I came up with are things like running random integer on $Test array and which ever gets highest/lowest gets 2 individuals and rest three. This would give a problem when I increase the size of $People array; to deal with that I though about using modulus to figure out what will be even number of $Test beforehand.
I can do this and other ideas but am pretty sure there has to be a better way to do this.
Clarifying your situation:
You want to distribute the values inside $People randomly amongst your $Test array. The problem you stated you are having is that the amount of values in $People isn't always perfectly dividable by the amount of values in $Test, and you aren't sure how to go about implementing code to distribute the values evenly.
Proposed solution:
You could obtain the values in a foreach loop randomly 1 by 1 from a shuffled version of $People and put them in a new array called $Result. You would also have a conditional checking if you have extracted all the values from the shuffled $People array: if($count>=$arrayCount) where $arrayCount=$count($shuffledPeople);. If you have obtained all the values, you first make the $bool value false (in order not to iterate through the while loop anymore, and then you break; out of the foreach loop.
$Result =[];//the array containing the results
$shuffledPeople = $People;
shuffle($shuffledPeople);//mixing up the array
$arrayCount = count($shuffledPeople);//finding the total amount of people
$count = 0;
$bool = TRUE;
while ($bool)
{
foreach($Test as $value)
{
$Result[$value][] = $shuffledPeople[$count];
$count++;
if ($count>=$arrayCount)
{
$bool = FALSE;
break;
}
}
}
To view the results, all you would need to do is:
foreach ($Result as $key => $value)
{
echo "{$key}: <br>";
if (is_array($value))
{
foreach ($value as $something)
{
echo "-->{$something}<br>";
}
}
else
{
echo "-->{$value}<br>";
}
}
I believe that this is what you want to do...
Assume that you have $people and $test arrays. You want to know how many people per test...
$ppt = ceil(sizeof($people)/sizeof($test));
Now, $ppt is the people per test. The next step is to shuffle up the people so they are randomly assigned to the tests.
shuffle($people);
Now, we can chunk up the people into sub-arrays such that each sub-array is assigned to a test. Remember, the chunks are random now because we shuffled.
$chunks = array_chunk($people, $ppt);
Now, everyone in $chunks[0] will take $test[0]. Everyone in $chunks[1] will take $test[1]. Everyone in $chunks[2] will take $test[2].

Splitting up an array formed by an api in PHP

I'm working on some stat tracking code for a game (yes, it's runescape. sue me).
I want to pull information from the high scores using an api which produces an array looking like this (captured using print_r)
Array
(
[getHiscore] => Array
(
[overall] => Array
(
[rank] => 61995
[lvl] => 2273
[totalxp] => 193310588
)
[attack] => Array
(
[rank] => 93406
[lvl] => 97
[totalxp] => 11747494
)
...and so on.
My question is how can i take what this api gives me and place it into a database table; I want to get an array such as this for a particular user and update their stats with it.
Would i use explode? It seems like the right idea to me but how would i actually use it to split the separate numbers and words?
My database is not totally realised yet, however each record will include a user name and then the level and total xp in each of 27 "skills". This almost certainly not best practice for database design but i'm as novice as they come so it's the best i can do.
You don't need to explode. It's an array and therefore it's already exploded. You need to iterate through it to build meaningful queries.
I'm not familiar with runescape so I don't know if your example is showing just the relevant fields of you need to discard some part. If it's the former, then you should try something like
$query="insert into stats_table (description, rank, lvl, totalexp) values (:description, :rank, :lvl, :totalext);";
$Statement = $DBConn->prepare($query);
foreach($fullArray as $description=>$subArray) {
$Statement->bindValue(':description',$description, PDO::PARAM_STR);
foreach($subArray as $key=>$value) {
$Statement->bindValue($key,$value, PDO::PARAM_STR);
}
$Statement->execute();
}
That will insert two rows containing
overall 61995 2273 193310588
attack 93406 97 11747494
PD: $DBConn is a PDO connection instance to whatever DB engine you're using.
Let's say this is all stored in the variable $ary:
$ary['getHiscore']['overall']['rank'] = 61995;
$ary['getHiscore']['overall']['lvl'] = 2273;
$ary['getHiscore']['overall']['totalxp'] = 193310588;
$ary['getHiscore']['attack']['rank'] = 93406;
$ary['getHiscore']['attack']['lvl'] = 97;
$ary['getHiscore']['attack']['totalxp'] = 11747494;
So, to get those values, it's:
$attackLevel = $ary['getHiscore']['attack']['lvl'];
If you
echo $attackLevel;
it would be 97.
Just pull the arrays out with a foreach loop and write some sql to insert the data. I don't know anything about your DB so if you want help there update your question please.
Simplest way to do this:
foreach($highscores as $highScoreType => $highScoreValues){
$rank = $highScoreValues['rank'];
$lvl = $highScoreValues['lvl'];
$totalXp = $highScoreValues['totalxp'];
//then it's up to you to put it into a table somehow.
}
$highScoreType will contain the values 'overall','attack',etc
This format of the foreach loop is extremely handy when iterating over an associative array (hash map/hash table, which is actually what all PHP arrays are underneath) will allow you to not only grab the value of the current pointed to entry, but also the key for that entry.
So, assume we have a single entry hashmap with key 'foo' and value 'bar'. If I want to show 'bar' I would simple
echo $map['foo'];//will output 'bar'
and if I put this into the above type of foreach loop
foreach($map as $fooKey => $barValue) {
echo $fooKey;//outputs 'foo'
echo $barValue;//outputs 'bar'
}

create a multidimensional array in a loop php

I've done a fair bit of googling and couldn't find anything that works, I'm just getting nothing back, this is probably something simple but there's a lot of variations that don't seem to match what I'm doing.
To give you an overall idea what I'm at, I'm accessing an API and getting back info as an object. There are comments and attachments, these are in separate arrays.
What i want to do is display the comments and attachments all together in the order of the date and time not separately.
I figured the best way is to create a loop through the comments array, then create a loop through the attachment array, then join both and sort by the date (epoch) and then loop through the whole merged loop echoing what i want. That should provide some context, right now i just want to create the multidimensional array for comments and i can figure out the rest.
$comments_holder = array();
//total number of comments in the array
$comment_total = $issue_json->fields->comment->total -1;
$i=1;
while ($i <= $comment_total)
{
//this is the date,time and timezone info for each comment
$raw_date = $issue_json->fields->comment->comments[$i]->updated;
$comments_holder[$i] = array();
//convert_sql_time just converts from 2012-11-04T16:33:00.936+600 into epoch time so i can sort the results later based on date
$comments_holder[$i]['comments_date'] = convert_sql_time($raw_date);
$comments_holder[$i]['comments_displayName'] = $issue_json->fields->comment->comments[$i]->author->displayName;
$comments_holder[$i]['comments_body'] = $issue_json->fields->comment->comments[$i]->body;
}
if everything is okay with data, this code will be enough for building such array:
$comments = $issue_json->fields->comment->comments;
$result = array();
foreach ($comments as $comment) {
$result[] = array(
'comments_date' => convert_sql_time($comment->updated),
'comments_displayName' => $comment->author->displayName,
'comments_body' => $comment->body,
);
}
print_r($result);
if comment->comments is an array, there is no need to keep it's count separately;
foreach is enough for iterating through the array and there is no need to keep separate variable for calculating array index;
[] notation will automatically increase array index and assigning array directly will do the trick(i.e. will result to multi dim array)

Autofill array with empty data to match another array size

I have 2 sets of arrays:
$dates1 = array('9/12','9/13','9/14','9/15','9/16','9/17');
$data1 = array('5','3','7','7','22','18');
// for this dataset, the value on 9/12 is 5
$dates2 = array('9/14','9/15');
$data2 = array('12','1');
As you can see the 2nd dataset has fewer dates, so I need to "autofill" the reset of the array to match the largest dataset.
$dates2 = array('9/12','9/13','9/14','9/15','9/16','9/17');
$data2 = array('','','12','1','','');
There will be more than 2 datasets, so I would have to find the largest dataset, and run a function for each smaller dataset to properly format it.
The function I'd create is the problem for me. Not even sure where to start at this point. Also, I can format the date and data arrays differently (multidimensional arrays?) if for some reason that is better.
You can do this in a pretty straightforward manner using some array functions. Try something like this:
//make an empty array matching your maximum-sized data set
$empty = array_fill_keys($dates1,'');
//for each array you wish to pad, do this:
//make key/value array
$new = array_combine($dates2,$data2);
//merge, overwriting empty keys with data values
$new = array_merge($empty,$new);
//if you want just the data values again
$data2 = array_values($new);
print_r($data2);
It would be pretty easy to turn that into a function or put it into a for loop to operate on your array sets. Turning them into associative arrays of key/value pairs would make them easier to work with too I would think.
If datas are related will be painful to scatter them on several array.
The best solution would be model an object with obvious property names
and use it with related accessor.
From your question I haven't a lot of hint of what data are and then I have to guess a bit:
I pretend you need to keep a daily log on access on a website with downloads. Instead of using dates/data1/data2 array I would model a data structure similar to this:
$log = array(
array('date'=>'2011-09-12','accessCount'=>7,'downloadCount'=>3),
array('date'=>'2011-09-13','accessCount'=>9), /* better downloadsCount=>0 though */
array('date'=>'2011-09-15','accessCount'=>7,'downloadCount'=>3)
...
)
Using this data structure I would model a dayCollection class with methods add,remove,get,set, search with all methods returning a day instance (yes, the remove too) and according signature. The day Class would have the standard getter/setter for every property (you can resolve to magic methods).
Depending on the amount of data you have to manipulate you can opt to maintain into the collection just the object data (serialize on store/unserialize on retrieve) or the whole object.
It is difficult to show you some code as the question is lacking of details on your data model.
If you still want to pad your array than this code would be a good start:
$temp = array($dates, $data1, $data2);
$max = max(array_map('count',$temp));
$result = array_map( function($x) use($max) {
return array_pad($x,$max,0);
}, $temp);
in $result you have your padded arrays. if you want to substitute your arrays do a simple
list($dates, $data1, $data2) = array_map(....
You should use hashmaps instead of arrays to associate each date to a data.
Then, find the largest one, cycle through its keys with a foreach, and test the existence of the same key in the small one.
If it doesn't exist, create it with an empty value.
EDIT with code (for completeness, other answers seem definitely better):
$dates_data1 = array('9/12'=>'5', '9/13'=>'3', '9/14'=>'7' /* continued */);
$dates_data2 = array('9/14'=>'12', '9/15'=>'1');
#cycle through each key (date) of the longest array
foreach($dates_data1 as $key => $value){
#check if the key exists in the smallest and add '' value if it does not
if(!isset( $date_data2[$key] )){ $date_data2[$key]=''; }
}

how to compare two arrays and find the count of match elements

i have two arrays i.e$ar1=array("Mobile","shop","software","hardware");and$arr2=arry("shop","Mobile","shop","software","shop")
i want to compare the elements of arr2 to arr1 i.e
foreach($arr2 as $val)
{
if(in_array($val, $arr1))
{
//mycode to insert data into mysql table
variable++; // here there should be a variable that must be increamented when ever match found in $arr2 so that it can be saved into another table.
}
$query="update table set shop='$variable',Mobile='$variable'.......";
}
the $variable should be an integer value so that for later use i can use this variable(shop i.e in this example its value should be 3) to find the match.
My question is how can i get the variable that will increamented each time match found.
Sorry, I don't fully understand the purpose of your code. You can use array_intersect to get common values and array_diff to get the unique values when comparing two arrays.
i want to compare the elements of arr2 to arr1 i.e
Then you are essentially doing the same search for shop three times. It's inefficient. Why not sort and eliminate duplicates first?
Other issues. You are comparing arr2 values with the ones in arr1, which means the number of repetation for "shop" will not be 3 it will be one. Doing the opposite might give you the number of repetation of arr1[1] in arr2 =3.
There are multitude of ways to solve this problem. If efficiency is required,you might wish to sort so you don't have to go beyond a certain point (say s). You can learn to use indexes. Infact the whole datastructure is revolved around these kinds of things - from quick and dirty to efficient.
Not sure I understand the connection between your two arrays. But you can use this to count how many items are in your second array:
$items = array("shop","Mobile","shop","software","shop");
$count = array();
foreach($items as $item)
{
if(isset($count[$item]))
{
$count[$item]++;
}
else
{
$count[$item] = 1;
}
}
print_r($count); // Array ( [shop] => 3 [Mobile] => 1 [software] => 1 )

Categories