I have a database which has 6 column A B C D E X, for each combination of ABCDE I have a different value of X.
I need a way to search through, that will allow all values of X for different combinations (for example all X when A=1, or all X when A=1 and B=2 etc)
My thought was to translate it into a 5-D array which looks like this:
Array[A][B][C][D][E]=X;
But now I'm trying to extract sub arrays, when I don't know how may of the dimensions will be constant. So I need to be able to extract all value of X for Array[1][5][][][] or Array[2][4][5][][]… etc.
And I'm totally stuck.
I'm trying to do 6 loops one inside another but I don't know how to handle those that are constant.
Help with ideas will be very very helpful.
Edit
Database:
A B C D E X
1 1 1 1 1 53
1 1 2 3 2 34
2 1 1 4 2 64
Turned it into an array:
Array[1][1][1][1][1]=53
Array[1][1][2][3][2]=34
For
Input: A=1
Output 53,34
Input A=1,B=1,C=1
Output: 53,
etc
Try this then
<?php
$arr = array();
$result = mysql_query("SELECT A,B,C,D,E,X FROM table_name ORDER BY A ASC,B ASC,C ASC,D ASC,E ASC");
if(mysql_num_rows($result) > 0) {
while($row = mysql_fetch_assoc($result)) {
array_push($arr,$row);
}
}
function search($arr,$values) {
$return = array();
foreach($arr AS $key => $value) {
$ok = true;
foreach(array('A','B','C','D','E') AS $letter) {
if(array_key_exists($letter,$values)) {
if($value[$letter] != $values[$letter]) {
$ok = false;
break;
}
}
}
if($ok) array_push($return,$value['X']);
}
return (($return) ? implode(',',$return) : false);
}
echo '<pre>';
print_r(search($arr,array('A' => 1)));
echo '</pre>';
?>
Related
Using a predefined array of numbers, how can I use PHP to generate a multi-dimensional array which groups all factor-pairs by their product?
Input array:
$array = array(1,2,3,4,5,6,7,8);
I want to display all factor-pairs for each product group that have more than one factor-pair.
In a case where there are no product groups that have more than one factor-pair, No pairs Found should be displayed.
Given the above input, this is my expected result:
1 6 and 2 3 // product group = 6
1 8 and 2 4 // product group = 8
2 6 and 3 4 // product group = 12
3 8 and 4 6 // product group = 24
*note as the input array increases in size, the output will display more than two factor-pairs per group.
This is my code from C++:
void findPairs(int arr[], int n)
{
bool found = false;
unordered_map<int, pair < int, int > > H;
for (int i=0; i<n; i++)
{
for (int j=i+1; j<n; j++)
{
// If product of pair is not in hash table,
// then store it
int prod = arr[i]*arr[j];
if (H.find(prod) == H.end())
H[prod] = make_pair(i,j);
// If product of pair is also available in
// then print current and previous pair
else
{
pair<int,int> pp = H[prod];
cout << arr[pp.first] << " " << arr[pp.second]
<< " and " << arr[i]<<" "<<arr[j]<<endl;
found = true;
}
}
}
// If no pair find then print not found
if (found == false)
cout << "No pairs Found" << endl;
}
This is your C++ code "translated" to PHP (mostly by search & replace).
90% of the translation was achieved by removing the variable types and prepending the variable names with $. The array PHP type is a mixture of array, list and map (aka hash, dictionary) and can be used for both $H and the values it contains (pairs of values).
function findPairs(array $arr, $n)
{
$found = false;
$H = array();
for ($i=0; $i<$n; $i++)
{
for ($j=$i+1; $j<$n; $j++)
{
// If product of pair is not in hash table,
// then store it
$prod = $arr[$i]*$arr[$j];
if (! array_key_exists($prod, $H))
$H[$prod] = array($i,$j);
// If product of pair is also available in
// then print current and previous pair
else
{
$pp = $H[$prod];
echo $arr[$pp[0]], " ", $arr[$pp[1]]
, " and ", $arr[$i], " ", $arr[$j], "\n";
$found = true;
}
}
}
// If no pair find then print not found
if ($found == false)
echo "No pairs Found\n";
}
$array = array(1,2,3,4,5,6,7,8);
findPairs($array, count($array));
And this is its output:
1 6 and 2 3
1 8 and 2 4
2 6 and 3 4
3 8 and 4 6
The simplest solution will work fine with a small array like your example but will use a lot of memory for bigger inputs. Basically, first calculate all products by using a nested loop. For every product, create a list of inputs that generate the product. Mind you that there might be more than 2 ways to get a certain result, so you might get an output like 1 12 and 2 6 and 3 4 for bigger lists.
For an input of size N, you need to store ((N -1) * N) / 2 tuples in memory, so that's something to keep in mind.
$input = [1, 2, 3, 4, 5, 6, 7, 8];
$products = [];
foreach ($input as $index1 => $value1) {
// Assuming you only want unique combinations, only combine this value with the other values coming after it
for ($index2 = $index1 + 1; $index2 < count($input); $index2++) {
$value2 = $input[$index2];
$product = $value1 * $value2;
// Make sure there is an entry in the $products array for adding this input to
if (!isset($products[$product])) {
$products[$product] = [];
}
// Add this input (formatted) to the list of possible inputs resulting in this product
$products[$product][] = sprintf('%d %d', $value1, $value2);
}
}
// Print all inputs resulting in the same products, if there are more than 1 way to produce the same output
foreach ($products as $inputs) {
if (count($inputs) > 1) {
echo implode(' and ', $inputs), PHP_EOL;
}
}
Will output
1 6 and 2 3
1 8 and 2 4
2 6 and 3 4
3 8 and 4 6
PHP code demo
<?php
ini_set("display_errors", 1);
$result=array();
$array = array(1,2,3,4,5,6,7,8);
$counter=0;
$noOfPairs=3;
while (count($result)!=$noOfPairs)
{
shuffle($array);
getPair($array);
}
print_r($result);
function getPair($array)
{
global $result;
$product=$array[0]*$array[1];
if(isset($result[$product]))
{
return false;
}
$result[$product][]=array($array[0],$array[1]);
unset($array[0]);
unset($array[1]);
foreach($array as $key1 => $value1)
{
foreach($array as $key2 => $value2)
{
if($value1*$value2==$product)
{
$result[$product][]=array($value1,$value2);
break;
}
}
if(count($result[$product])==2)
{
break;
}
}
if(count($result[$product])==1)
{
unset($result[$product]);
}
}
I didn't speed test my method but I think it is more direct and easier to read.Basically, it generates the full multi-dim array, then filters out any subarrays that have only one pair, then if there are subarrays remaining, it displays them. Simple.
My method performs without any count() calls and without incrementing key variables. It uses the very fast isset() call to filter the result array and array_walk() to iterate and implode() the qualifying subarrays.
As a bonus feature, I've used range() to dynamically generate the input array which is determined by entering the highest value for the array. Of course, if you want to find pairs for [3,4,5], then you'll have to modify this process or simply revert to your original style -- it depends on your project expectations.
Code: (Demo)
function findPairs($maxfactor){
$array=range(1,$maxfactor); // spare yourself having to write out the array
foreach($array as $v1){
$array=array_slice($array,1); // shrink array as you go to avoid needless iterations
foreach($array as $v2){
$result[$v1*$v2][]="$v1 $v2"; // generate multi-dim output array using products as outer keys
}
}
$result=array_filter($result,function($a){return isset($a[1]);}); // remove elements with < 2 pairs
if(!$result){
echo "No pairs found";
}else{
array_walk($result,function($a){echo implode(' and ',$a),"\n";});
}
}
findPairs(8);
Output:
1 6 and 2 3
1 8 and 2 4
2 6 and 3 4
3 8 and 4 6
I have a code in which foreach inside another foreach.
$order_id = '1,1,8';
$order_no_first= 'F,SH,C';
$order_id1 = explode(",", $order_id);
$order_no_first1 = explode(',', $order_no_first);
foreach($order_id1 as $ord_id){
foreach($order_no_first1 as $ord_no_first){
if($ord_id != '') {
$this->receipt->chageBagStatus($ord_id, $ord_no_first);
$add = $this->receipt->addJobOrderNew($ord_id, $ord_no_first, $bag_no);
}
}
}
Now the above code iterates 3 times resulting 9 rows in mysql.
//Current Output
order_id orderr_no_first
-------- ---------------
8 C
8 SH
8 F
1 C
1 SH
1 F
1 C
1 SH
1 F
The above output is wrong. I want the output as below,
//Required Output
order_id orderr_no_first
-------- ---------------
8 C
1 SH
1 F
I know it's because am using nested foreach. but I don't know how to solve this issue. Is there any solution. Thankyou.
just use one foreach like this,
foreach($order_id1 as $key => $ord_id){
if($ord_id != '') {
$this->receipt->chageBagStatus($ord_id, $order_no_first1[$key]);
$add = $this->receipt->addJobOrderNew($ord_id, $order_no_first1[$key], $bag_no);
}
}
I hope this will work for you
$order_id = '1,1,8';
$order_no_first= 'F,SH,C';
$order_id1 = explode(",", $order_id);
$order_no_first1 = explode(',', $order_no_first);
rsort($order_id1);
asort($order_no_first1);
$i = 0;
foreach($order_id1 as $ord_id){
echo $ord_id." ".$order_no_first1[$i]."<br/>";
$i++;
}
`
I am trying to figure out how I can loop out possible combinations of a x amount of integers to sum a specifik number.
Let's say, I have number 7 and I need to figure out how I can sum that number with integers in pairs 3.
1+2+4 = 7
3+3+1 = 7
5+1+1 = 7
2+2+3 = 7
Repeated combinations of numbers doesn't interest me, e.g.:
1+2+4 = 7
2+4+1 = 7
4+2+1 = 7
Anyone got any ideas of how I should proceed to reach this result?
Thanks.
Here is the solution for your problem.
function printPartitions($target, $max, $s){
if($target === 0 )
echo $s;
else
{
if($max > 1)
{
printPartitions($target, $max-1, $s);
}
if($max <= $target)
{
printPartitions($target-$max, $max, $max . " " . $s);
}
}
}
printPartitions(5, 5, "<br/>");
You have to specify the $target Value, $max value.
e.g.
printPartitions(7, 7, "<br/>");
It will give you output like:
1 1 1 1 1 1 1
1 1 1 1 1 2
1 1 1 2 2
1 2 2 2
1 1 1 1 3
1 1 2 3
2 2 3
1 3 3
1 1 1 4
1 2 4
3 4
1 1 5
2 5
1 6
7
I've got a solution to my problem. I feel I should defientely share it here, if anyone would ever need it. My solutions is based on this post: https://stackoverflow.com/a/19067884/3293843
<?php
function sampling($chars, $size, $combinations = array()) {
# if it's the first iteration, the first set
# of combinations is the same as the set of characters
if (empty($combinations)) {
$combinations = $chars;
}
# we're done if we're at size 1
if ($size == 1) {
return $combinations;
}
# initialise array to put new values in
$new_combinations = array();
# loop through existing combinations and character set to create strings
foreach ($combinations as $combination) {
foreach ($chars as $char) {
$new_combinations[] = $combination .'#'. $char;
}
}
# call same function again for the next iteration
return sampling($chars, $size - 1, $new_combinations);
}
// example
$chars = array('1', '2', '3','4');
$target = 7;
$maxLengthOfIntegers = 3;
$output = sampling($chars, $maxLengthOfIntegers);
$repeatedEntries = array();
//presenting the output
foreach($output as $out){
$explodeOut = explode('#',$out);
sort($explodeOut);
if(array_sum($explodeOut) == $target){
$sortedPattern = implode('',$explodeOut);
if(!in_array($sortedPattern,$repeatedEntries)){
echo $sortedPattern.'<br/>';
$repeatedEntries[] = $sortedPattern;
}
}
}
?>
Thank you for your time and efforts.
Regards,
Jacob
you can try this algorithm
$ans = array();
for($i=1;$i<=5;$i++)
{
$i1 = 7-$i;
$i2 = intval($i1 - $i);
$value = $i."+".$i1."+".$i2;
$ans = array_unshift($ans,$value);
}
print_r($ans);
hope this helps.. PLease let me know
I have come to this part of script so far:
dif($result>0)
{
$ii=0;
$jj=0;
while (odbc_fetch_row($result))
{
for ($jj = 1; $jj <= odbc_num_fields($result); $jj++)
{
$rr[$ii][$jj]=odbc_result($result,$jj);
if(is_null($rr[$ii][$jj]))
$rr[$ii][$jj] = noData;
echo $rr[$ii][$jj];
echo "<br />";
}
$ii++;
}
}
This works good for creating and populating dynamic tables. But i need also to create dynamic number of single line arrays which consist of column values of arrays i get previously.
Example:
if i get
Array1
2012.01.01 10 20 30
2012.01.02 1 2 3
2012.01.03 11 22 33
i need to convert to
Array2
2012.01.01 2012.01.02 2012.01.03
Array3
10 1 11
Array4
20 2 22
Array5
30 3 33
As i mentioned before the first part of script is needed, so is there a possibility to use result to create single line arrays for further use? I suppose i'm missing something...
What is wrong with a for loop and adding the elements to an array?'
$rr = array(array(1,2,3,4,5),array(6,7,8,9,0),array(11,22,33,44,55));
$result = array();
for($j=0;$j<count($rr[0]);$j++){
$col = array();
for($i=0;$i<count($rr);$i++) {
array_push($col,$rr[$i][$j]);
}
array_push($result,$col);
}
print_r($result);
for a demo see this codepad: http://codepad.org/wgSCtoMV
Im trying to loop through a mysql table and check if a row contains the number I specify:
Here is what I have:
mysql table with numbers:
mysql table:
no1|no2|no3|no4|no5
1 3 5 2 6
4 7 8 9 8
2 6 9 1 0
...
For Example: I have number
4 5 3 7
So in the first row i should get a total of 2 as there are numbers 3 and 5 first row and this numbers are in the number I have specified.
In the second row I should get a total of 1 as only a 4 is in the row and the number i have specified.
And in the last row total should be 0 as there are no matches.
I hope its clear.
I have tried the following but it dont work I hope someone can help me work it out thanks in advance.
$lottono1=4;
$lottono2=5;
$lottono3=3;
$lottono4=7;
$no1 = 0;
$no2 = 0;
$no3 = 0;
$no4 = 0;
do { ?>
// i done the following if code for each numbers but
//putting this only to take less space
if (($row_Recordset1['no1']=$lottono1) || ($row_Recordset1['no1']=$lottono2) || ($row_Recordset1['no1']=$lottono3) || ($row_Recordset1['no1']=$lottono4)) {
$no1=1;
}
while ($row_Recordset1 = mysql_fetch_assoc($Recordset1));
select *,
if(no1 in (4,5,3,7),1,0)+
if(no2 in (4,5,3,7),1,0)+
if(no3 in (4,5,3,7),1,0)+
if(no4 in (4,5,3,7),1,0)+
if(no5 in (4,5,3,7),1,0) as found
from table
Well for one, your operators are wrong in your "if" conditions (you're setting rather than comparing).
Regardless i'd do something more like:
$numbers_to_match = array(4,5,3,7) ;
$query = mysql_query("select * from `table` where ____",connection_here);
$matches[] = array();
$i=0;
while($r=mysql_fetch_array($query)){
$matches[$i]=0;
foreach($r as $val){
if (in_array($val,$numbers_to_match)){
$matches[$i]++;
}
}
$i++;
}
print_r($matches);
Untested, but this should give you an array that lists the number of matches for each row
To accomplish with PHP/MySQL you can do the following:
$query = 'SELECT * FROM table';
$result = mysql_query($query) or die();
$matchValues = array(4,5,3,7);
while($row = mysql_fetch_array($result)){
$counter = 0;
foreach($matchValues as $value)
{
if(in_array($value, $row))
{
$counter++;
}
}
print "Searched row and found $counter matches<br/>";
}