I'm trying to automate something we do at work. I get a list of 20+ organizations and he number of guests they have. I then assign them table numbers. Each table holds eight people. So first I assign companies that are multiples of eight, then I start grouping the rest based off size.
Conceptually how do I do this. My initial thought is to create an array that has org name and size. Then add a column with the MOD of the 8. Then doing a for each item in the array that has a mod 1 and find if there is one with a mod 7. Except I don't know how to compare them, and am fuzzy removing them from an array, I spent all my time in SQL and rarely use arrays. Thanks in advance.
I think it's important for users to note the complexity of some requests. Had I not enjoyed this particular exercise, I wouldn't have taken the time to throw this together.
Assuming you have a data array like so:
<?php
$companies = array(
'Verizon' => 75,
'GE' => 42,
'JP Morgan' => 38,
'ATT' => 38,
'Chevy' => 11,
'Gray' => 4,
'Individuals' => 0
);
?>
You would execute this script:
<?php function completeList($companies,$table_size){echo "<table>\n";echo "<tr><th>Company</th><th>Total</th></tr>\n";foreach($companies as $c=>$q){echo "<tr><td>$c</td><td>$q</td></tr>\n";}echo "</table>\n\n";fullTables($companies,$table_size);}function fullTables($companies,$table_size){$straglers=array();$extras=0;echo "<table>\n";echo "<tr><th>Company</th><th>FullTables</th><th>Extras</th></tr>\n";foreach($companies as $name=>$qty){echo "<tr><td>$name</td>";$tables=$qty/$table_size;if(!strpos($tables,'.'))$tables=number_format($tables,1);$totals=explode('.',$tables);$extras=$qty;if($qty>1)$extras=(intval($totals[1])/100)*$table_size;if($extras>$table_size&&$qty>=$table_size)$extras=$extras/10;if($extras<1&&$extras!=0)$extras=$extras*10;if($qty<=$table_size)$extras=$qty/1;echo "<td>$totals[0]</td><td>{$extras}</td>";$straglers[$name]=$extras;echo "</tr>\n";}echo "</table>\n\n";mixRemaining($companies,$straglers,$table_size);}function mixRemaining($companies,$straglers,$table_size){$assoc=array();$numeric=array();foreach($straglers as $c=>$q){array_push($assoc,$c);array_push($numeric,$q);}$i=0;$l=count($straglers);$jokers=0;$individuals=0;echo "<table>\n";echo "<tr><th>Companies</th><th>Grouped</th><th>Supply</th></tr>\n";while($i<$l){if($i!=$l-1&&$numeric[$i]>0){$members=$numeric[$i]+$numeric[$i+1];if($members>$table_size){$jokers=$members-$table_size;$remainder=$numeric[$i+1]-$jokers;$members=$numeric[$i]+$remainder;}else{$spaces_left=$table_size-$members;$jokers=0;}$mingled="$assoc[$i] and {$assoc[$i+1]}";echo "<tr><td>$mingled</td>";echo "<td>($numeric[$i]+{$numeric[$i+1]})$members</td>";if($jokers){echo "<td class=\"open\">$jokers extra {$assoc[$i+1]} members</td>";}else echo "<td class=\"over\">$spaces_left spaces left</td>";if($jokers&&$i===($l-1))echo "<td>[+$jokersextra{$assoc[$i+1]}member(s)inlasttable.]</td>";$i++;echo "</tr>\n";}else{($jokers>0)?$final="$jokers extra people.":$final='all tables full!';break;}}echo "</table>\n\n";summary($companies,$straglers,$table_size,$final);}function summary($companies,$straglers,$table_size,$final){$total_companies=count($companies);$total_people=array_sum($companies);$total_tables=$total_people/$table_size;echo "<h4 id=\"summary\">$total_companies companies with $total_people people using $total_tables tables leaving $final</h4>\n";} ?>
By calling it with completeList($companies,8);, where 8 is the maximum table capacity:
<div id="table-table">
<h4>Assuming you have a maxium capacity of 8 per table:</h4>
<?php completeList($companies,8); ?>
</div>
I threw in some style for style. You can see a sample of the output here.
The only thing I couldn't figure out is where's that cookie at?
Good luck! It was actually a fairly complicated script, but it seems to work perfectly :)
<?
$companies = array(
'GE' => 42,
'ATT' => 38,
'Chevy' => 11
);
foreach($companies as $name => $qty){
echo "$name: \n";
$tables = $qty/8;
$totals = explode('.',$tables);
$extras = (intval($totals[1])/100)*8;
if($extras>8) $extras = $extras/10;
echo "$totals[0] plus {$extras} extra. <br>\n";
}
?>
GE: 5 plus 2 extra.
ATT: 4 plus 6 extra.
Chevy: 1 plus 3 extra.
Now I guess the only question is where's my damn cookie. :)
Related
I struggle with below.
I have 2 query results from a Database. One Query returns always present data like a set of slots (i.e. 1-9) those get always displayed. And the other query returns only if it is present, like a job. When it is active than it gets a slot id assigned.
Note: There not always the same amount of Jobs as it is for Slots. Slots always 1-3 and in total 3, but Jobs can be 1,2 or even 5 with a Slot Status 0 and a single with an assigned Slot number, like below it is 1.
$ArrSlot = array(
'TABLE_NUMBER' => 1,
'TABLE_NUMBER' => 2,
'TABLE_NUMBER' => 3);
$ArrJob = array(
'TABLE_NUMBER' => 0,
'TABLE_NUMBER' => 0,
'TABLE_NUMBER' => 0,
'TABLE_NUMBER' => 1);
Here it turns tricky, I want to do an foreach and echo an 'X' only if the $ArrJob == $ArrSlot.
Not sure how to tackle this.
What I did was:
Run the queries first, than do the foreach and echo a result from a query result which is not inner of the foreach.
<?php foreach($ArrSlot as $SlotList) {
if (trim($ArrJob["TABLE_NUMBER"]) == $SlotList["TABLE_NUMBER"])
{ echo trim($ArrJob["STATUS"]);
} else
{ echo "0";}
?>
I used a ternary, but it didn't succeed. I might be doing something very simple wrong, sorry guys doing this for quite some hours...
Use array_intersect(). Consider...
$resultArr = array_intersect($ArrSlot,$ArrJob);
foreach($resultArr as $result)
{
print_r($result);
}
I couldn't find a solution for this problem. I may solve this with novice if else function for every specific data but, it would be very simple.
So here is my array example:
//I get data from mysqli
while ($recordsnumber = mysqli_fetch_assoc($result1)) {
$records = array(
'id' => $recordsnumber['Id'],
'mapid' => $recordsnumber['ChallengeId'],
'players' => $recordsnumber['PlayerId'],
'time' => $recordsnumber['Score'],
);
$recordstable[] = $records;
}
So my data becomes like:
id[1] mapid[2] players[1] time[2310]
id[2] mapid[1] players[4] time[1920]
id[3] mapid[2] players[2] time[2340]
id[4] mapid[3] players[1] time[2180]
id[5] mapid[1] players[2] time[1540]
id[6] mapid[3] players[4] time[2210]
id is primary key in table, there maybe 10 maps, but some of them may not be played yet. There maybe 50 players but some of them may not be play yet.
First I want to make a table for each mapid, then I want to list players which have played that maps. Then I want to sort those players with best times(less is better). So it should be like this:
Map1
Rank-Player-Time
1. Player2 1540
2. Player4 1920
Map2
Rank-Player-Time
1. Player1 2310
2. Player2 2340
I'm getting player names and map names from another table. There is no problem with that. I can show times like 23:10 with wordwrap. No problem with that either.
I think something like:
$i=1;
foreach ($recordstable[mapid] as $table){
if ($table = $i) {
//echo $recordstable[] in lots of <tr><td> ^^
}
i++;
}
But it can't get which $recordstable row will it list. Then I know I should use usort to sort with best times.
So I'm stuck.
I'll note that this is a very special case, hence the question to begin with. Under normal circumstances, such a function would be simple:
I have an array named $post_id, which contains 5 values
(Each numerical)
In order to print each value in the array, I use the following loop:
.
for ($i = 0; $i < $num; $i++)
{
echo $post_id[$i] . ' ';
}
...Which prints the following: 49, 48, 47, 46, 43
3. In my database, I have a table that looks like this:
post_categories
_____________________
post_id | category
__________|__________
43 | puppies
43 | trucks
46 | sports
46 | rio
46 | dolphins
49 | fifa
4. So, using the data in the array $post_id, I'd like to loop a database query to retrieve each value in the category column from the post_categories table, and place them into uniquely named arrays based on the "post id", so that something like...
echo $post_id_49[0] . ' ', $post_id_46[1];
...Would print "fifa rio", assuming you use the above table.
An example of such a query:
//Note - This is "false" markup, you'll find out why below
for ($i = 0; $i < $num; $i++)
{
$query = "SELECT category FROM post_categories WHERE post_id = $post_id[$i]";
fakeMarkup_executeQuery($query);
}
Why is this a "special" case? For the same reason the above query is "false".
To elaborate, I'm working inside of a software package that doesn't allow for "normal" queries so to say, it uses it's own query markup so that the same code can work with multiple database types, leaving it up to the user to specify their database type which leaves the program to interpret the query according to the type of database. It does, however, allow the query to be stored in the same "form" that all queries are, like "$result = *query here*" (With the only difference being that it executes itself).
For that reason, functions such as mysql_fetch_array (Or any MySQL/MySQLi function akin to that) cannot, and will not work. The software does not provide any form of built in alternatives either, effectively leaving the user to invent their own methods to achieve the same results. I know, pretty lame.
So, this is where I'm stuck. As you'd expect, all and any information you find on the Internet assumes you can use these MySQL & MySQLi functions. What I need, is an alternative method to grab one array from the results of a looped query per loop. I simply cannot come to any conclusion that actually works.
tl;dr I need to be able to (1) loop a query, (2) get the output from each loop as it's own array with it's own name, and (3), do so without the use of functions like mysql_fetch_array. The query itself does not actually matter, so don't focus on that. I know what do with the query.
I understand this is horrifically confusing, long, and complicated. I've been trudging through this mess for days - Close to the point of "cheating" and storing the data I'm trying to get here as raw code in the database. Bad practice, but sure as heck a lot easier on my aching mind.
I salute any brave soul who attempts to unravel this mess, good luck. If this is genuinely impossible, let me know so that I can send the software devs an angry letter. All I can guess is that they never considered that a case like mine would come up. Maybe this is much more simple then I make it to be, but regardless, I personally cannot come to an logical conclusion.
Additional note: I had to rewrite this twice due to some un explained error eliminating it. For the sake of my own sanity, I'm going to take a break after posting, so I may not be able to answer any follow up questions right away. Refer to the tl;dr for the simplest explanation of my need.
Sure you can do this , here ( assuming $post_ids is an array of post_id that you stated you had in the OP ), can I then assume that I could get category in a similar array with a similar query?
I don't see why you couldn't simply do this.
$post_id = array(49, 48, 47, 46, 43);
$result = array();
foreach($post_id as $id)
{
//without knowing the data returned i cant write exact code, what is returned?
$query = "SELECT category FROM post_categories WHERE post_id = $id";
$cats = fakeMarkup_executeQuery($query);
if(!empty($cats)) {
if(!isset($result[$id])){
$result[$id] = array();
}
foreach( $cats as $cat ){
$result[$id][] => $cat;
}
}
}
Output should be.
Array
(
[49] => Array
(
[0] => fifa
)
[46] => Array
(
[0] => sports
[1] => rio
[2] => dolphins
)
[43] => Array
(
[0] => puppies
[1] => trucks
)
)
Ok, assuming you can run a function (we'll call it find select) that accepts your query / ID and returns an array (list of rows) of associative arrays of column names to values (row), try this...
$post_categories = [];
foreach ($post_id as $id) {
$rows = select("SOME QUERY WHERE post_id = $id");
/*
for example, for $id = 46
$rows = [
['category' => 'sports'],
['category' => 'rio'],
['category' => 'dolphins']
];
*/
if ($rows) { // check for empty / no records found
$post_categories[$id] = array_map(function($row) {
return $row['category'];
}, $rows);
}
}
This will result in something like the following array...
Array
(
[49] => Array
(
[0] => fifa
)
[46] => Array
(
[0] => sports
[1] => rio
[2] => dolphins
)
[43] => Array
(
[0] => puppies
[1] => trucks
)
)
So, here is the deal. I searched everywhere for the answer, but didn't find antyhing concrete ehough for my case, maybe i'm googling something wrong. Btw, i wanted phpmyadmin to be NOT in english, but it automatically changes back to cro... so... :/ hope you will understand enough to help me with solution...
Link to my table
TIP: I know how to get a solution through mysql, so you don't have to write those answers.
Here is the deal. This table is made by joining 2 other tables, because that was the only way to get all required data(that i must display) from one query (and that is relevant because later i will have to implement sort, which won't work otherwise).
I managed to pull out data which doesn't repeat itself with function, so this is what my solution looks by now:
1
tema1
opis1
sastanak.jpeg
2012-11-26 16:29:58
2012-11-26 17:30:00
2
tema2
opis2
sastanak.jpeg
2012-11-27 16:29:58
2012-11-29 18:30:00
3
tema3
opis3
sastanak.jpeg
2012-11-28 16:29:58
2012-11-28 17:05:00
4
tema4
opis4
sastanak.jpeg
2012-11-29 16:29:58
2013-11-29 21:42:00
and so on...
That's ok, but that is not all I need.
I'm still 2 steps away.
I need to count all id's, where current id is equal to previous. That means that solution would be:
5 (id_sastanka=1 appears 5 times in table)
5 (id_sastanka=2 appears 5 times),
6 (id_sastanka=3 appears 6 times),
6 (id_sastanka=4 appears 6 times) and so on.
I tried various combinations, but all give everything BUT correct result, so please help. I know the solution is in something simple, but I just can't seem to reach it. So this actually represents number of users who were invited to a meeting, by meeting's id.
I need to count all id's where status=1. I know how to do all of this with mysql, so that is not the question, I need the answer in php...
Solutions to this should be:
4 (four "1" in "status" where "id_sastanka"=1),
4 (four "1" in "status" where "id_sastanka"=2),
5 (five "1" in "status" where "id_sastanka"=3),
3 (three "1" in "status" where "id_sastanka"=4)....
this represents number of users who attended those meetings.
I'm a beginner, and I really need help with this, so I hope you won't bear a grudge.
I guess, that each row of your data represents as array. So, I'll write code for the following data structure:
$rows = array(
0 => array(
'id_sastanka' => 1,
'naziv' => 'tema1',
'opis' => 'opis1',
'slika' => 'sastanak.jpeg',
'posetak' => '<...>',
'zavrsetak' => '<...>',
'dnevny_red' => '<...>',
'id_korisnika' => '<...>',
'status' => '1'
),
1 => array(...),
2 => array(...),
...
);
$prev_id = null;
$prev_id_counter = array();
$ids_status_counter = array();
foreach($rows as $row) {
if ($prev_id == $row['id_sastanka']) {
$prev_id_counter[$row['id_sastanka']] = (isset($prev_id_counter[$row['id_sastanka']])) ? ++$prev_id_counter[$row['id_sastanka']] : 1;
}
$prev_id = $row['id_sastanka'];
if ($row['status'] == 1) {
$ids_status_counter[$row['id_sastanka']] = (isset($ids_status_counter[$row['id_sastanka']])) ? ++$ids_status_counetr[$row['id_sastanka']] : 1;
}
}
So, in array $prev_id_counter result for the first case and $ids_status_counter store result for the second one. Arrays have format ['id_sastanka'] => case counter
I'm trying to do a sort in my WP_Query on a custom field. The custom field contains strings such as "E100", "E500" and "E123b". I would like to sort numerically on these values, i.e. sort on the custom field as if the characters weren't there.
My query looks like this:
$subpages = new WP_Query(array(
"post_type" => "page",
"meta_key" => "[customFieldNameHere]",
"orderby" => "meta_value_num",
"order" => "ASC",
"posts_per_page" => 5000
));
But it doesn't work. It does some sort of sort, but it's not numerical. Is it possible to strip all characters/letters from the field, and then do a numerical sort on the remaining values, or is there some other way to solve this?
You can't sort a string with letters as if it were all numbers. If you try you will get a alphanumerical sort-- more or less what you'd do if you were alphabetizing something but it makes numbers look odd because it matches up all the first characters, then the second, and so on making numbers look like:
1
10
101
2
20
I don't know of anything built into MySQL that will do what you want, nor does WP_Query have any such feature. The best solution I have is to pull your results unsorted, and sort them later. You want to pull unsorted so the database doesn't do extra work.
$subpages = new WP_Query(array(
"post_type" => "page",
"meta_key" => "[customFieldNameHere]",
"posts_per_page" => 5000
));
$sorted = array();
foreach ($subpages as $s) {
$kname = preg_replace('/[^0-9]+/','',$s->customFieldNameHere]);
$sorted[$kname] = $s;
}
// you may need
// ksort($sorted);
var_dump($sorted);
One problem is going to be collisions. If you end up with two matching $knames you will clobber data, and frankly, that seems pretty likely if you have a lot of data.
I ended up removing the leading E from all strings. Doesn't really solve the original problem, with numerical sorting of strings, but at least it works now.