so I have an array that looks like this (easier to see then the raw output)
0 | from:2 page | to:1 split
1 | from:1 split | to:3 page
2 | from:1 split | to:4 page
3 | from:1 split | to:5 page
4 | from:3 page | to:0 join
5 | from:4 page | to:0 join
6 | from:5 page | to:0 join
7 | from:8 page | to:0 join
8 | from:0 join | to:12 page
9 | from:1 split | to:8 page
10 | from:12 page | to:10 end
11 | from: start | to:2 page
what I would like to do is to somehow parse through it and come up with the following:
0 | start
1 | page
2 | split 3, 4, 5, 8
3 | page
4 | end
so essentially I'm trying to organize this into a final array that follows the path from start to finish.
Rules of engagement:
Where there is a split: combine the "to page" into a sub array, and where there is a "to join", remove the reference. and where there is a "from join to page" just make the page. so final output should look something like this:
array(
'start',
'page',
'split' => array (
3, 4, 5, 8
),
'page',
'end'
)
UPDATE:
here is the raw format I'm working with
Array
(
[operators] => Array
(
[0] => Array
(
[type] => join
)
[1] => Array
(
[type] => split
)
[2] => Array
(
[type] => page
)
[3] => Array
(
[type] => page
)
[4] => Array
(
[type] => page
)
[5] => Array
(
[type] => page
)
[8] => Array
(
[type] => page
)
[9] => Array
(
[type] => start
)
[10] => Array
(
[type] => end
)
[12] => Array
(
[type] => page
)
)
[links] => Array
(
[0] => Array
(
[fromOperator] => 2
[toOperator] => 1
)
[1] => Array
(
[fromOperator] => 1
[toOperator] => 3
)
[2] => Array
(
[fromOperator] => 1
[toOperator] => 4
)
[3] => Array
(
[fromOperator] => 1
[toOperator] => 5
)
[4] => Array
(
[fromOperator] => 3
[toOperator] => 0
)
[5] => Array
(
[fromOperator] => 4
[toOperator] => 0
)
[6] => Array
(
[fromOperator] => 5
[toOperator] => 0
)
[7] => Array
(
[fromOperator] => 8
[toOperator] => 0
)
[8] => Array
(
[fromOperator] => 0
[toOperator] => 12
)
[9] => Array
(
[fromOperator] => 1
[toOperator] => 8
)
[10] => Array
(
[fromOperator] => 12
[toOperator] => 10
)
[11] => Array
(
[fromOperator] => 9
[toOperator] => 2
)
)
)
``
Boo Yahh!!
I had to nap on it, but now I got that 4 sure.
<?php
$array = array (
'operators' =>
array (
0 =>
array (
'type' => 'join'
),
1 =>
array (
'type' => 'split'
),
2 =>
array (
'type' => 'page'
),
3 =>
array (
'type' => 'page'
),
4 =>
array (
'type' => 'page'
),
5 =>
array (
'type' => 'page'
),
8 =>
array (
'type' => 'page'
),
9 =>
array (
'type' => 'start'
),
10 =>
array (
'type' => 'end'
),
12 =>
array (
'type' => 'page'
),
),
'links' =>
array (
0 =>
array (
'fromOperator' => 2,
'toOperator' => 1
),
1 =>
array (
'fromOperator' => 1,
'toOperator' => 3
),
2 =>
array (
'fromOperator' => 1,
'toOperator' => 4
),
3 =>
array (
'fromOperator' => 1,
'toOperator' => 5
),
4 =>
array (
'fromOperator' => 3,
'toOperator' => 0
),
5 =>
array (
'fromOperator' => 4,
'toOperator' => 0
),
6 =>
array (
'fromOperator' => 5,
'toOperator' => 0
),
7 =>
array (
'fromOperator' => 8,
'toOperator' => 0
),
8 =>
array (
'fromOperator' => 0,
'toOperator' => 12
),
9 =>
array (
'fromOperator' => 1,
'toOperator' => 8
),
10 =>
array (
'fromOperator' => 12,
'toOperator' => 10
),
11 =>
array (
'fromOperator' => 9,
'toOperator' => 2
)
)
);
Code:
//Flatten to simplify [$op_id => $array['operators'][n]['type']]
//array_combine and array_keys, just makes sure the keys match
//the original array, because we are missing a few keys (7,8 and 11)
//we have to do this or we lose those references.
$arr_op = array_combine(array_keys($array['operators']), array_column($array['operators'], 'type'));
//print_r($arr_op);
//get our instruction list - combine data to simplify.
//this saves us a bit of work doing the lookup and managing multiple arrays
$instructions = [];
foreach($array['links'] as $link){
$instructions[] = [
'fromOperator' => $link['fromOperator'],
'fromOp' => $arr_op[$link['fromOperator']], // we need them keys to match here
'toOperator' => $link['toOperator'],
'toOp' => $arr_op[$link['toOperator']] //and here
];
}
//print_r($instructions);
$opp_id = array_search('start',$arr_op); //9 start
//print_r($opp_id);
$i=0;
$output = [];
//loop as long as we have some instructions to process
while(count($instructions)){
//get the current key of the array
$key = key($instructions);
//is this our instruction?
//we are forced to {potentially} loop the whole array to find it
//we cannot use array search (even after flattening it out) because of the duplicates
if($instructions[$key]['fromOperator'] == $opp_id){
//get and remove the instruction - array reduction
$instruction = array_splice($instructions, $key, 1)[0];
//print_r($instruction);
//print_r($instructions);
//just for sanity checks.
echo "{$i} | from:{$instruction['fromOp']} {$instruction['toOperator']} | to:{$instruction['fromOperator']} {$instruction['toOp']}\n";
//if the last operation is end, use it as there is no fromOp = end
$opperation = 'end' == $instruction['toOp'] ? 'end' : $instruction['fromOp'];
//process instruction
switch($opperation){
case 'join':
//skip
break;
case 'split':
//split has to be done as a group
$output['split']=array_column(array_filter($array['links'],function($ins)use($opp_id){return $ins['fromOperator']==$opp_id;}),'toOperator');
break;
default: //start, page, end
$output[] = $opperation;
//when we find the end, break the switch, break the while
if($opperation == 'end') break 2;
break;
}//end switch
//get the operation key for the next instruction as we consumed it, Yum!
$opp_id = $instruction['toOperator'];
++$i;
}//end if
//move the array pointer forward, or reset on false (start over when we hit the end of the array)
if(false === next($instructions)) reset($instructions);
}//end while
echo "\n";
print_r($output);
Output
0 | from:start 2 | to:9 page
1 | from:page 1 | to:2 split
2 | from:split 4 | to:1 page
//Some "magic" happens here and we warp to 0
3 | from:page 0 | to:4 join
4 | from:join 12 | to:0 page
5 | from:page 10 | to:12 end
Array
(
[0] => start
[1] => page
[split] => Array
(
[0] => 3
[1] => 4
[2] => 5
[3] => 8
)
[2] => page
[3] => end
)
Sandbox
Limitations
Because PHP array keys are unique, your forced to group all the "split" operations into one lump. With your current input array structure there is no "real" way around it, even without "using split as a key". (hopefully this illiterates the issues)
//The #{n} in the first column, is the (apx) order this thing runs in.
//#(hashtag) will be used for all numbers with a # (in my explanation below)
//if they don't have a # and are code, assume they are the second column value (in my explanation below)
#2 - 0 | from:2 page | to:1 split //--> start of split
#3 - 1 | from:1 split | to:3 page //--> go to 3
#dup - 2 | from:1 split | to:4 page // -> go to 4
#4 - 3 | from:1 split | to:5 page // -> go to 5
#dup - 4 | from:3 page | to:0 join //<-- if you go to 0 -> 12 -> end
#5 - 5 | from:4 page | to:0 join //<-- if you go to 0 -> 12 -> end
#dup - 6 | from:5 page | to:0 join //<-- if you go to 0 -> 12 -> end
#6 - 7 | from:8 page | to:0 join
#7 - 8 | from:0 join | to:12 page
#dup - 9 | from:1 split | to:8 page //--> go to 8 end of split
#8 - 10 | from:12 page | to:10 end // {exit}
#1 - 11 | from: start | to:2 page
As you can see above, the #dup ones all come from opp:1 or $array['operators'] = [1 =>['type' => 'split']], but there is only 1 to:1 at #2 and 4 from:1 items. So we are forced to split the execution of these because you cant go to 4 items at the same time for 1 item. We can do this with a loop, or with this big huge mess I did there.
For example take #3 our last good path:
#3 - 1 | from:1 split | to:3 page //--> go to 3
~4 - 4 | from:3 page | to:0 join //<-- if you go to 0 -> 12 -> end
~5 - 8 | from:0 join | to:12 page // way out of wack now.
~6 - 10 | from:12 page | to:10 end {premature termination}
As you see we cannot follow those paths, so we are forced to process these as a group. If we did that (follow the path) we would have only processed #1, #2, #3, ~4, ~5 and ~6 and then the program ends. This is what happened in my previous answer (basically) and how I knew it wasn't correct. Also due to the duplicated 0 we can't process any of those or well wind up at the end shortly. I don't see any {other} way to solve that given the structure of the data.
How I did it (briefly)
The "trick" here was manually mapping out how it runs, above.
Using that knowledge I built an instruction list (to reduce complexity), so we are dealing with one array without the lookups for the operation names, I called that list $instructions (creative I know).
Next if($instructions[$key]['fromOperator'] == $opp_id)
TRUE: we just eat that $instruction = array_splice($instructions, $key, 1)[0]; which removes and returns a portion of the array. So our list of instructions is constantly being reduced as we are able to process them.
FALSE: we continue to the next instruction and reset the array if the array pointer is at the end. if(false === next($instructions)) reset($instructions); and start back at 1 (in this list) on the next instruction.
Because there is no "real" way to order this, we may have to loop over the array several time, this is easier to do by removing each instruction as we process it.
Then it's pretty trivial to do a switch and collect our output, with a bit of "finagling" with the "split stuff" and the end operation.
the "finagling" is just pulling an array of all the toOperator from the main array where the fromOperator has the same int as the split has for it's key (or 1 in this case)
Lastly we either run out of array items, or we hit this if($opperation == 'end') break 2; which breaks out of both the switch and the while loop. Who knew you could do that with break {this guy}...
I left a bunch of comments in there, hopeful this explains how I did it and what the main issue was.
Improvements
Where I have this monstrosity, which just gets a flat array of all the toOperator values for all items that are "Splits" (all dynamic like). I can come up with at least 5 ways to do this, this was just the way I picked.
$output['split']=array_column(array_filter($instructions,function($ins)use($opp_id){return $ins['fromOperator']==$opp_id;}),'toOperator');
You could iterate over each "split" and recursively call the switch "somehow". Because I am removing each instruction, the first "Split" gets pulled out of the instruction list before we can check if it's a split. This makes it a bit difficult to work with. However you can do this (if you need to fix that):
$instructions = array_splice($instructions, $key, 0, [instructions]);
Which should put it back in the instruction list. The magic of array_splice even if that is a bit counter productive. Then you just need to loop over them, and if they don't have a goto 0 you could follow that path where it leads. Which may solve some issues with ordering, that may or may not happen. One other issue here is you will get multiple page values in the output, as I just skip over them (pun intended). So keep that in mind if you try to iterate over it. The way I did it wasn't necessary to deal with that. But the basic idea is to functionality (make part or all of it a function and then) call it multiple times for the splits as they happen.
One other issue, that I didn't bother fixing, is that not all the split items are are actually removed from the instruction list. In this example this doesn't matter because we have the end tag. However it would be pretty easy to clean that up when doing the above improvements.
In any case I will leave that as an exercise for the reader.
Final words
PS: if you numbered it like above, it would have saved me a TON of time. It was a fun challenge though.
Hope it helps, this is about the best you can get with the data you provided due to the above issues. There may be some minor performance things to be gained etc, but that pretty much covers it.
Cheers!!
*PPS: yes I know my spelling and grammar suck. Oh the joys of dyslexia. I supose one cannot be good at everything.... It takes me about a billion edits to get it somewhat readable.
Related
I have a database that stores how users were referred into the system like so:
| user_id | referrer_id |
| 3 | 2 |
| 4 | 3 |
| 5 | 3 |
| 6 | 4 |
| 7 | 4 |
| 8 | 5 |
| 9 | 5 |
| 10 | 6 |
| 11 | 10 |
| 12 | 10 |
and I would like to display a specific user's network, i.e., the user, the other users which s/he referred directly, and also other users referred by the direct referrals, in an array.
So far, I've been able to create a recursive function
// The actual get_downlines() function
function get_downlines($upline_id) {
// Init the UsersMatrix model
$um_model = model('UsersMatrix');
$um_model->select('user_id')->where('upline_id', $upline_id);
$downlines_check = $um_model->findAll(5);
$downlines = [];
if ( ! empty($downlines_check) ) {
foreach($downlines_check as $check) {
$downlines[] = $check->user_id;
}
}
return $downlines;
}
// User to check
$user = 3;
// The initial network array
$network_array['user_network'][0] = [
'id' => $user,
'text' => "user-$user"
];
// Get the user's network
function get_network($referrer, $network_array){
// This function basically runs a SELECT user_id FROM users WHERE referrer_id = $referrer_id
// and returns the user_ids in an array: get_downlines()
$downlines = get_downlines($referrer);
if (count($downlines) > 0){
// Loop through the downlines
foreach($downlines as $downline){
// Update the array
array_push($network_array['user_network'], [
'id' => $downline,
'text' => "user-$downline",
]);
// Check for the downlines of this user and inner levels
get_network($downline, $network_array);
}
}
// Return the network array
return $network_array;
}
With this, I expect that when I run the get_network(3, $network_array);, I should get an array like so:
Array
(
[user_network] => Array
(
[0] => Array
(
[id] => 3
[text] => user-3
),
[1] => Array
(
[id] => 4
[text] => user-4
),
[2] => Array
(
[id] => 5
[text] => user-5
),
[3] => Array
(
[id] => 6
[text] => user-6
),
[4] => Array
(
[id] => 7
[text] => user-7
),
[5] => Array
(
[id] => 8
[text] => user-8
),
[6] => Array
(
[id] => 9
[text] => user-9
),
[7] => Array
(
[id] => 10
[text] => user-10
)
)
)
instead, the page dies with a maximum execution time error. But if I use a user ID without an indirect referrer, it works well. E.g user id 10.
Where am I going wrong?
I have trouble with some calculation in Codeigniter. Please check attached image below
https://imgur.com/HuSBkXJ
That data fetching from the database , the sale column is fine but I having trouble with monthly sale
1st day of every month sale (10) and monthly sale (10) are same, but from second day sale is correct(8), monthly sale has to be 1st day sale + second day sale(10+8 = 18). for third day sale is fine, monthly sale should be (18+20=38). the calculation going like this up to end of the month, Same process again stating from next month
How do we calculate in codeigniter, The above image i have created in excel sheet for demonstration purpose.
Model view
public function fetchSaleData()
{
$this->db->join('stock_shop','stock_shop.shop_id = stock_sale.shopId');
$this->db->join('stock_products','stock_products.product_id = stock_sale.productID');
$thisMonth=date('m');
$this->db->where('MONTH(DateOfSale)',$thisMonth);
$query= $this->db->get("stock_sale");
return $query->result_array();
}
controller view
public function salesView()
{
$data['sales']=$this->Query_sale->fetchSaleData();
$data['shops']=$this->Query_sale->fetchShop();
$this->load->view('stock/shop_sales_view',$data);
}
since you're not showing table structures or any other insight, I'll only suggest an approach based on my own code which you may feel free to adapt to your specific needs, along with the assumptions I make along the way
Assumption #1: the model returns an array in which each element contains the date and the sold units on such date
This would look like this
+-----------------+
| array data |
+------------+----+
| 2020-01-01 | 10 |
+------------+----+
| 2020-01-02 | 20 |
+------------+----+
| 2020-01-03 | 5 |
+------------+----+
| 2020-01-04 | 8 |
+------------+----+
On array form, this may look like this:
$ar = array(
0 => array(
'date' => '2020-01-01',
'units_sold' => 10,
),
1 => array(
'date' => '2020-01-02',
'units_sold' => 20,
),
2 => array(
'date' => '2020-01-03',
'units_sold' => 5,
),
3 => array(
'date' => '2020-01-04',
'units_sold' => 8,
),
);
and so on until the end of the month. Lets call the returned fields date and units_sold as in the above example
now that you have the data loaded in a variable ($ar) you can loop through it and keep tabs on the accumulated total on each loop.
$accum = 0; // keep track of accumulated total
$i = 0; // keep track of array index
foreach ($ar as $a)
{
$accum += $a['sales'];
$ar[$i]['accum'] = $accum;
$i++;
}
Upon running, this code will:
Iteration 0: For 2020-01-01, sales=10, accumulated=10
Iteration 1: For 2020-01-02, sales 20, accumulated=30
Iteration 2: For 2020-01-03, sales 5, accumulated=35
...and so on until the month is over
The above can be verified with a print_r or var_dump (I use print_r... like this: print print_r($ar,true);):
print_r output
Array
(
[0] => Array
(
[date] => 2020-01-01
[sales] => 10
[accum] => 10
)
[1] => Array
(
[date] => 2020-01-02
[sales] => 20
[accum] => 30
)
[2] => Array
(
[date] => 2020-01-03
[sales] => 5
[accum] => 35
)
[3] => Array
(
[date] => 2020-01-04
[sales] => 8
[accum] => 43
)
)
So, now that you've succesfully pushed a whole new element in your result array, you can send it over to the view and display it in tabular form as you need
Let's say I have this simple table where pos_level is the level of the position and pos_under is that the PID of the position on top of it.
In level 1, I have 'General Manager' and 'Supervisor'.
In level 2, under 'General Manager(PID: 1)' : 'Asst. Manager', under 'Supervisor(PID: 2)' : 'Marketing'.
In level 3, under 'Asst. manager(PID: 3)' : 'Sales' & 'Purchase', under 'Marketing(PID:2) : none.
+-----+-----------------+-----------+-----------+
| PID | pos_name | pos_level | pos_under |
+-----+-----------------+-----------+-----------+
| 1 | General Manager | 1 | 0 |
| 2 | Supervisor | 1 | 0 |
| 3 | Asst. Manager | 2 | 1 |
| 4 | Sales | 3 | 3 |
| 5 | Purchase | 3 | 3 |
| 6 | Marketing | 2 | 2 |
+-----+-----------------+-----------+-----------+
Now how do I make the query so I get a nested array as the result like this:
Array
(
[0] => Array
(
[pos_level] => 1
[pos_name] => General Manager
[pos_under] => Array
(
[0] => Array
(
[pos_level] => 2
[pos_name] => Asst. Manager
[pos_under] => Array
(
[0] => Array
(
[pos_level] => 3
[pos_name] => Sales
)
[1] => Array
(
[pos_level] => 3
[pos_name] => Purchase
)
)
)
)
)
[1] => Array
(
[pos_level] => 1
[pos_name] => Supervisor
[pos_under] => Array
(
[0] => Array
(
[pos_level] => 2
[pos_name] => Marketing
[pos_under] => Array
(
)
)
)
)
)
I have tried using multiple queries and using array_push using the results, but I have like around 100+ pos_name and I think it is messy, I have also tried using loop to keep running queries for each level and under, also tried using multiple tables for each level, but I am hoping I can use only 1 table and able to query the result as the nested array above for further use in my application.
All answers, comments, and suggestions are very welcomed. Thank you.
As mentioned above in the comments I doubt in general that the approach you are following is a good one. That is because it will not scale! You try to take all entries from your database and pack them into a single, hierarchical array. That means you create several copies of each entry in memory. What will happen with a growing number of entries? You face a constantly raising memory consumption of your script which will obviously make it fail ultimately.
Nevertheless I accepted the challenge and implemented a small demonstration of how to cleverly construct such nested structures with the help of references. Such references not only simplify the creation of nested structures, they also reduce the memory footprint by preventing that entries are copied by value again and again. This however will not solve the general scaling issue with this approach mentioned above, it can only help to reduce it.
I also took the liberty to make a small modification to your approach and introduce a new property "pos_over" to hold entries under an entry. Two reasons for that:
it usually is not a good idea to remove original available data and especially not to replace it with an altered meaning
the meaning of the term "pos_under" is to describe under what other entry an given entry is (to be) placed. But from the "upper" entries point of view the ones "below" it should not be referenced by "pos_under", right? That would contradict the original meaning of that term.
The following code does not depend on a database for demonstration purpose. Instead it reads the raw data from a CSV string and parses that. The actual building of the desired structure structure is marked further down by a comment. Also it should be mentioned that the code expects the original data to reference other entries only after they have been declared. So if processed from top to bottom each entry under another one can expect that other one to already exist.
Note, that the actual code to build that nested structure consists of only a mere 12 clever lines...
<?php
// the raw CSV data
$csvText = <<<CSV
PID|pos_name|pos_level|pos_under
1|General Manager|1|0
2|Supervisor|1|0
3|Asst. Manager|2|1
4|Sales|3|3
5|Purchase|3|3
6|Marketing|2|2
CSV;
// praparation of CSV data
foreach (explode("\n", $csvText) as $csvRow) {
$csvData[] = str_getcsv($csvRow, '|');
}
$csvTitle = array_shift($csvData);
$table = [];
foreach ($csvTitle as $titleKey=>$titleValue){
foreach ($csvData as $csvRow=>$csvColumn) {
foreach ($csvColumn as $csvKey=>$csvValue) {
$table[$csvRow][$csvTitle[$csvKey]] = $csvValue;
}
}
}
// creation of the structure
$catalog = [];
$structure = [];
foreach ($table as $key=>&$entry) {
$entry['pos_over'] = [];
if ($entry['pos_under'] == 0) {
$structure[] = &$entry;
$catalog[$entry['PID']] = &$structure[count($structure)-1];
} else {
$catalog[$entry['pos_under']]['pos_over'][] = &$entry;
$catalog[$entry['PID']] = &$catalog[$entry['pos_under']]['pos_over'][count($catalog[$entry['pos_under']]['pos_over'])-1];
}
}
// demonstration output
print_r($structure);
The output of above experiment is:
Array
(
[0] => Array
(
[PID] => 1
[pos_name] => General Manager
[pos_level] => 1
[pos_under] => 0
[pos_over] => Array
(
[0] => Array
(
[PID] => 3
[pos_name] => Asst. Manager
[pos_level] => 2
[pos_under] => 1
[pos_over] => Array
(
[0] => Array
(
[PID] => 4
[pos_name] => Sales
[pos_level] => 3
[pos_under] => 3
[pos_over] => Array
(
)
)
[1] => Array
(
[PID] => 5
[pos_name] => Purchase
[pos_level] => 3
[pos_under] => 3
[pos_over] => Array
(
)
)
)
)
)
)
[1] => Array
(
[PID] => 2
[pos_name] => Supervisor
[pos_level] => 1
[pos_under] => 0
[pos_over] => Array
(
[0] => Array
(
[PID] => 6
[pos_name] => Marketing
[pos_level] => 2
[pos_under] => 2
[pos_over] => Array
(
)
)
)
)
)
I am trying to build a website that will display the text in multiple languages.
I have a table 'text' with all the languages. If the text does not exist in the chosen language it has to display the default language.
query SELECT * FROM text WHERE TextId = 10
results in
Id TextId LanguageId Text
10 10 1 first name
13 10 2 名前
If I r_print this result I get something like this
Array ( [0] => Array ( [0] => 10 [Id] => 10 [1] => 10 [TextId] => 10 [2] => 1 [LanguageId] => 1 [3] => first name [Text] => first name )
[1] => Array ( [0] => 13 [Id] => 13 [1] => 10 [TextId] => 10 [2] => 2 [LanguageId] => 2 [3] => 名前 [Text] => 名前 ) )
How can I check that LanguageId 2 exist in this array ?
the problem is that it is possible that TextId 2 and Id 2 can also exist in this array.
Is this possible to do with in_array()?
Here is a function that can check if LanguageId equals a special value .
function isLanguageIdExists($yourArray , $LanguageId){
$exists=false;
foreach($yourArray as $array){
if(isset($array['LanguageId'])&& $array['LanguageId'] == $LanguageId){
$exists=true;break;
}
}
return $exists;
}
$exist = isLanguageIdExists($yourArray , 2);//return true or false
You can check by isset the key and match the value in php.
$dataArray = array(
0 => array(0 => 10 ,'Id' => 10, 1 => 10, 'TextId' => 10, 2 => 1, 'LanguageId' => 1),1 => array(0 => 10 ,'Id' => 10, 1 => 10, 'TextId' => 10, 2 => 1, 'LanguageId' => 1)
);
foreach($dataArray as $value) {
if(isset($value['LanguageId']) && $value['LanguageId'] == 2) {
echo 'language ID 2 is available';
}
}
Working Demo
After giving this some more thought I came up with a maybe not so elegant solution.
Instead of getting an array back I modified the SQL Query to give one row back with the default language (English) and a user selected language (Japanese).
It uses two left joins. This shows that I received (some) training in SQL but am really not at ease with multidimensional arrays.
Query
def_text = text in default language
usr_text = text in user chosen language
$table01 = "text";
$query="SELECT $table01.TextId,
text_def.Text as def_text,
text_usr.Text as usr_text
FROM $table01
LEFT JOIN $table01 as text_def ON $table01.TextId = text_def.TextId AND text_def.LanguageId = $_SESSION[default_language]
LEFT JOIN $table01 as text_usr ON $table01.TextId = text_usr.TextId AND text_usr.LanguageId = $_SESSION[language]
WHERE $table01.TextId=$mess;";
after getting back the results it is easy to check with isset() or empty() to see if the text is available in the user selected language
I have a multidimensional array like this:
Array (
[0] => Array ( [ans_id] => 1 [ans_name] => PHP Hypertext Preprocessor [ques_id] => 1 [right_ans] => Yes [ques_name] => What is the acronym of PHP? [section_id] => 1 [section_name] => PHP )
[1] => Array ( [ans_id] => 2 [ans_name] => Preety Home Page [ques_id] => 1 [right_ans] => No [ques_name] => What is the acronym of PHP? [section_id] => 1 [section_name] => PHP )
[2] => Array ( [ans_id] => 3 [ans_name] => Programmed Hypertext Page [ques_id] => 1 [right_ans] => No [ques_name] => What is the acronym of PHP? [section_id] => 1 [section_name] => PHP )
[3] => Array ( [ans_id] => 4 [ans_name] => Programmed Hypertext Preprocessor [ques_id] => 1 [right_ans] => No [ques_name] => What is the acronym of PHP? [section_id] => 1 [section_name] => PHP ) )
My table is like this:
ans_id ans_name ques_id right_ans
1 PHP Hypertext Preprocessor 1 Yes
2 Preety Home Page 1 No
3 Programmed Hypertext Page 1 No
4 Programmed Hypertext Preprocessor 1 No
5 Andy Suraski 12 No
6 Zeev Gutman 12 No
7 Rasmus Lerdorf 12 Yes
8 Perl 12 No
I want to retrieve the answers in sets of common question id's
i.e. one set of all answers for Ques_id='1', 2nd set of all answers for ques_id='12', etc.
I am supposed to use this code:
foreach($all_ans_cat as $r)
{
echo $r['ans_id']." ".$r['ans_name']."<br>";
}
This is retrieving all the values present in the table as one set and again in the 2nd set the same values are being displayed.
Select all answers sorted by ques_id and generate array with structure needed
$questions = array();
$prevQuestionId = null;
foreach ($all_ans_cat as $r) {
if ($r['ques_id'] !== $prevQuestionId) {
$questions[] = array();
}
$questions[sizeof($questions)-1][] = $r;
$prevQuestionId = $r['ques_id'];
}
Result array would be:
0:
- [ans1, ques1]
- [ans2, ques1]
...
1:
- [ans5, ques13]
- [ans6, ques13]
...
...
you can use a query with group by and aggregate function
have a look at
http://www.w3schools.com/sql/sql_groupby.asp