I have a fairly simple (at least I thought simple) task I'm trying to achieve but for the life of me I can't think of the best way of doing it in php.
Note I'm trying to avoid using nested multi-dimensional arrays.
What I want to do is a simple 2 axis reference table which I can query/look up against.
0 | 1 | 2 | 3 | 4 | 5
0 5 0 0 0 0 0
-
1 0 2 0 1 0 0
-
2 0 0 0 7 0 1
-
3 1 2 4 10 1 0
-
4 0 0 0 0 0 0
-
5 0 3 4 0 1 0
Then I want to query it so lookup_table(3,3) would return 10. I also need to update the values in the table so like add_lookup_table(3,3,1) would change location 3,3 to 11 or some variation of.
So far I know I can achieve it with multidim arrays however want to avoid this because its just going to be a pain in the ass getting and setting each time.
I thought about a list() but php's lists aren't really lists so that goes out the window.
What I'm after is suggestions/recommendations for a better way of doing this.
you can just use a single array like so
$array = array(
5, 0, 0, 0, 0, 0,
0, 2, 0, 1, 0 , 0
..etc...
);
then each key is just $array[$row * 6 + $column]
so $array[3*6 + 3]
or define your array as something like
$array["3.3"] = 10;
both of the above are BAD ways to do it when a multidimensional array exists and is well suited for the task.
you list the reason you dont want to use it as "getting and setting each time" - what ever the solution, you will have to get and set to populate it.
The real solution here seems to be the one you wish to avoid
you MAY want to check
http://php.net/manual/en/spl.datastructures.php
That has extra structures
Related
I have the Document CompetitionsDocument like this...
Name
Position
Carl
Center
Carl
First
Carl
Last
Carl
Last
Mariah
Center
Mariah
Center
Mariah
Last
Mariah
Last
I would like to get a grouped table like this...
Name
First
Center
Last
Carl
1
1
2
Mariah
0
2
2
Used tools:
Symfony 4.4
Doctrine for MongoDB
MongoDB
My code is like this...
$builder->group()
->field('id')
->expression(
$builder->expr()->field('name')->expression('$name')
)
->field('first')
->sum(
$builder->redact()->cond(
$builder->expr()->gte('$position', 'First'), 1, 0
)
)
->field('center')
->sum(
$builder->redact()->cond(
$builder->expr()->gte('$position', 'Center'), 1, 0
)
)
->field('last')
->sum(
$builder->redact()->cond(
$builder->expr()->gte('$position', 'Last'), 1, 0
)
);
But I don't know how to add conditions that add 1 or 0 depending on the value.
Note: The function gte() returns error. I can't use 0 or 1 in the second and third parameter. I should use '$$PRUNE' or '$$DESCEND'
My data in table t1 as below (only 2 record),
+-----------+-----------------+----------+
| shid | lvlmin | lvlmax |
+-----------+-----------------+----------+
| 1 | 1 | 10 |
| 2 | 5 | 10 |
+----------------------------------------+
My php code is:
$userinfo[0] = '9';
$ghunt = DB::fetch_all("SELECT shid FROM t1
WHERE lvlmin <= ".$userinfo[0]." AND lvlmax >= ".$userinfo[0].
"ORDER BY rand() LIMIT 5");
print_r($ghunt);
Result got 2 array:
Array ( [0] => Array ( [shid] => 2 ) [1] => Array ( [shid] => 1 ) )
How do I do when the array result is less than the LIMIT 5 in mysql query, auto use the array result in $ghunt to fill up the array?
What I mean is:
Array (
[0] => Array ( [shid] => 2 )
[1] => Array ( [shid] => 1 )
[2] => Array ( [shid] => 2 )
[3] => Array ( [shid] => 1 )
[4] => Array ( [shid] => 1 )
)
The shid can be random place in array.
Why don't you do something like this?
If (count($ghunt) < 5){
$realResultCount = count($ghunt);
for ($i = realResultCount; $i <= 5; $i++){
$ghunt[$i] = $ghunt[rand(0,realResultCount-1)];
}
}
Basically, what above code does is, if ghunt has less than 5 records in it, it tops it up to 5, by randomly selecting records out of initially returned records.
I don't code PHP, but I can describe one way you can achieve your goal simply. Most languages have a MOD operator, usually % - the php manual page for mod is here
It gives us the remainder of a division operation, so 10 mod 3 is 1, because 10 divided by 3 is 9 remainder 1
A useful property of MOD then, is that it always cycles between 0 and 1 less than what you're modding by. If you mod an incrementing number by 5, the result will always be 0,1,2,3,4,0,1,2,3,4 in a cycle. This means you can have a for loop with some incrementing number, mod by an array length and the result will be an integer that is certainly an array index. If the loop variable goes higher than the end of the array, the mod operator will make it wrap round to the start of the array again
MyArray[ 1746262848 mod MyArray.length ]
Will certainly not crash, even if the array only has 2 items
So for your case, just have a loop.. make he following pseudo code into PHP
// run the loop 5 times
For I as integer = 0 to 4 do
Print MyArray[ i mod MyArray.length ]
If you have 2 items in your array, A and B, it will simply print ABABA
If you have 3 items A B C it will print ABCAB
Hopefully this info will be helpful to you for implementing a solution in php for this, and many future problems. Mod can be really useful for implementing various things when working with arrays
I have an array called $helloArray which looks like
[peach] => 1
[banana] => 1
[apple] => 1
[pineapple] => 1
[grapefruit] => 2
[tomatoe] => 2
[giger] => 1
[watermelon] => 1
Database columns look like
City peach banana apple pineapple grapfruit tomatoe ginger watermelon
Tokyo 0 0 0 500 0 0 0 0
DC 50 55 0 0 0 0 0 0
NY 0 0 0 0 0 500 0 0
Rome 0 0 0 0 90 0 0 0
SQL Statment that I used
$sql = "SELECT peach,banana,apple,pineapple,grapfruit,tomatoe,ginger,watermelon";
$sql .= " FROM TestTable2";
$sql .= " WHERE city ='NY'";
Question:
How do I loop through the array and then the variable names (aka column names) names so that
so that we get NY and Rome values of 2 and 1 for the rest. Below is my code that I have tried, not to mention it not working
foreach ($helloArray as $key =>$value){
for($i=0;$i<=odbc_num_fields($connection);$i++)
{ if (odbc_result($connection,$i) > 0) {
echo $value; }
}
}
OKay, not sure if I completely understand your question without an output sample, but I'm guessing you want:
Tokyo => 1
DC => 1
NY => 2
Rome => 2
If so, your approach is wrong. Don't pull data and then massage it, construct your SQL to return the data you want.
SELECT City, CASE WHEN grapefruit > 0 THEN 2 WHEN tomatoe > 0 THEN 2 WHEN peach > 0 THEN 1 WHEN banana > 0 THEN 1 WHEN ...
If it has to be data driven then sort your hello array by descending values and then use it to generate the SQL case conditions and return vals
-- edit --
Okay, but the code sample above, you are looping through your array as key=>value pairs. So first pass, you're on peach=>1, then you loop through every column in the return result (peach, watermelon, etc) and check it's value is greater than 0 and if it is then you output value from your array. (peach = 1)
Because there is no comparison between the fieldname and the key of the array, you are simply going to output 1 for each column while on peach, 1 for each column while on banana, etc. While I am assuming you are wanting to check if the field NAMED peach is greater than zero and if so, then output 1, and if the field named watermelon is greater than zero then output 2, you need to modify your loop. Drop the odbc_num_field and use the odbc_result syntax to specify the column name you want to retrieve. odbc_result($connection, $key) > 0.
But going by your original question it sounds like that isn't really what you are looking for, but instead want a city assigned a certain value based on the largest number returned by those field comparisons described above (NY = 2) in which case my original answer stands and you just need to use SQL to return that value for each city.
I'm trying to Calculate Income Points for MLM network Users (i.e).,
I'm having five types of kits such as Rs.0/-, Rs.1000/-, Rs.2000/-, Rs.4000/-, Rs.10000/- .
Once the kit is purchased a unique pin and user id will generate for each individual kit like
If 2 number of 2000/- kit purchased means userid and pin will be
2000100 539fdda37c435 and
2000101 5395b0d8b66d1 .....
Then Based on new user sponsor id(Sponsor id will be old user), registration will be proceed with Group left and right.
Now what's my problem is While calculating income point of a user how can i take their children user from top to bottom. I'd strucked in MYSQL Query.
For Example.,
now how can i get each node's value for a parent node(1) to root node(12) from this dynamic tree in php ??
I struck in this loop concept.,
Thanks IN Advance.,
database architecture
id par lev lef rgt status wallet userstatus
1 1 1 2 3 1 0 0
2 2 2 4 5 1 0 0
6 3 2 6 7 1 0 0
8 4 3 8 9 1 0 0
9 5 3 10 11 1 0 0
10 6 3 12 13 1 0 0
11 7 3 0 0 1 0 0
Apologise for a vague title.
What is the best way to pass a finite number of properties(e.g. read, write, execute, ...). I think I could do this like these permissions - count the sum of some numbers assigned to properties - 1,2,4,8,16... Is it the best easy to do this and what algorithm should I use to get the summands - for example if I have 17 - how could I calculate that this is 16 and 1?
Thanks.
You could use Bitwise Operators. This way you can compare the actual bits of an integer, Here's how it works:
Bit Pattern
8 4 2 1
1 0 0 0 = 8
0 1 1 1 = 7
0 1 1 0 = 6
0 1 0 1 = 5
0 1 0 0 = 4
0 0 1 1 = 3
0 0 1 0 = 2
0 0 0 1 = 1
0 0 0 0 = 0
So,
6 & 4 = 4
Means show me the bits that are present in both 6 and 4.
Compare '0 1 1 0' and '0 1 0 0' and you will see that the second bit '4' is the only bit populated in both, so return 4.
Or
7 & 3 = 3
Means show me the bits that are present in both 7 and 3.
Compare '0 1 1 1' and '0 0 1 1' and you will see that the third (2) and fourth (1) bits are populated in both, so return 3 (2 + 1).