I don't speak very good English, not sure about title so will try to explain what i need to do:
I am making log parser.
I have 3 dynamic arrays (read from .log file) containing corresponding elements:
$personName //array of strings, can contain same name
$itemName //array of strings, can contain same name
$itemAmount //array of numbers
Sample arrays:
$personName = array("Adam", "Maria", "Adam", "Adam");
$itemName = array("paper", "paper", "pen", "paper");
$itemAmount = array(11, 25, 2, 64);
I would like to sort (by person and item) and count (by amount) those arrays, eg. to print:
Total there are '100' 'paper' and '2' 'pen'.
'Adam' have '75' 'paper' and '2 'pen'.
'Maria' have '25' 'paper'.
This would allow me to get % of each item each person have, eg.:
'Adam' have '75'% of all 'paper' and '100'% of all 'pen'.
'Maria' have '25'% of all 'paper'.
I have arrays with unique names:
$persons = array_keys (array_flip ($personName));
$items = array_keys (array_flip ($itemName));
I did tried different combinations of for loops with foreach, but I struggle to find any solution.
Can somebody help me to get right approach?
(sorry if this is too basic, i really tried to look for solution and I'am very new to programming, started learning 3 days ago with this project)
Thanks!
Like this:
<?php
$personName = array("Adam", "Maria", "Adam", "Adam", "Mihai");
$itemName = array("paper", "paper", "pen", "paper", 'pencil');
$itemAmount = array(11, 25, 2, 64, '18');
$items = array();
$persons = array();
foreach($itemName as $id => $name){
$items[$name] += $itemAmount[$id]; // we are adding amount for each item to $items array
$persons[$personName[$id]][$name] += $itemAmount[$id]; // we are adding every item with amount to each persons
}
echo "Total there are "; // we are looping in each $items to display totals
$i = 0;
foreach($items as $nr => $item){
echo "'".$item."' '".$nr."'";
if($i < count($items)-2){ // this is for 'and' or ',' in case of multiple items
echo ", ";
} elseif($i < count($items)-1){
echo " and ";
}
$i++;
}
echo '<br />';
foreach($persons as $one => $value ){ // we are looping in each persons to display what they have
echo "'".$one."' have ";
$i = 0;
foreach($value as $val => $number){
echo "'".$number."' '".$val."'";
if($i < count($value)-2){ // this is for 'and' or ',' in case of multiple items
echo ", ";
} elseif($i < count($value)-1){
echo " and ";
}
$i++;
}
echo '.<br />';
}
// print_r($items); // will result in all items
// print_r($persons); // will result in every person with every item
?>
Now you can manage %.
Related
I am a rookie beginner with PHP, i was wondering how i could add up the total number from 1 array + the total number of another array together. I managed to make this code with help from stackoverflow answers on google. I don't know why but it's no where explained or i am looking over it. Been looking for almost an hour to make this work. Here is the code:
<?php
$array = array(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19);
$odds = array();
$even = array();
foreach($array as $val) {
if($val % 2 == 0) {
$even[] = $val;
} else {
$odds[] = $val;
}
}
$array = array();
foreach($even as $key => $val) {
$array[] = $val;
if(isset($odds[$key])) {
$array[] = $odds[$key];
}
}
echo '<b>Oneven</b> ';
print_r($odds);
echo '<br><br><br>';
echo "Bovenstaande <b>oneven</b> getallen bijelkaar opgeteld = " . array_sum($odds) . "\n";
echo '<br><br><br><hr style="margin-top:2%;margin-bottom:4%;">';
/* Array nummer 2 */
$array = array(20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40);
$odds = array();
$even = array();
foreach($array as $val) {
if($val % 2 == 0) {
$even[] = $val;
} else {
$odds[] = $val;
}
}
$array = array();
foreach($even as $key => $val) {
$array[] = $val;
if(isset($odds[$key])) {
$array[] = $odds[$key];
}
}
echo '<b>Even</b> ';
print_r($even);
echo '<br><br><br>';
echo "Bovenstaande <b>even</b> getallen bijelkaar opgeteld = " . array_sum($even) . "\n";
?>
So i don't know how to do it in another way but i have array 1 code at first and then code 2 begins with another array.
The thing is that i want to make a program that includes the odd numbers from 1 to 19 and the even numbers from 20 to 40 and then count the total of those 2 array's. Is there a way to do this in 1 code and count up the total of those 2 array's together. I already have that part of code that it counts the array, in code 1 that is 100 and in code 2 it is 330.
330+100=430 that's the output that i want. Why is that so hard? haha...
I appreciate the help and time effort.
First off, there's a lot of complexity involved in creating the initial array and then extracting only the odd numbers. This complexity can be eliminating by using the range and array_filter functions like so:
$odds = array_filter(range(1, 19), function($elem) {
return $elem & 1;
});
$even = array_filter(range(20, 40), function($elem) {
return $elem % 2 == 0;
});
to calculate sum of the sum of odds plus the sum of even, you can simply merge them together and use array_sum in the same you are doing for the individual arrays
$totalSum = array_sum(array_merge($odds, $even))
As #Darragh pointed out in the comments, you can simplify the array creation by specifying a step parameter for the range function.
$odds = range(1, 19, 2) // start at 1, go up to 19, by increments of 2
I know how to loop through equal arrays like this
foreach( $codes as $index => $code ) {
echo 'The Code is '.$code;
echo 'The Name is '.$names[$index];
}
Not sure how to loop through these 2 arrays and still manage to get all values when both arrays have different number of elements.
$code = array(R9,R10,R11,R12);
$names = array(Robert,John,Steve,Joe,Eddie,Gotham);
...how to loop through these 2 arrays and still manage to get all values when both arrays have different number of elements.
You can use for loop for this.
The solution is:
Take length of the longest array as the condition for for loop.
Use array_key_exists() function to check whether the index exists in the particular array or not, and display the element accordingly.
So your code should be like this:
$code = array("R9","R10","R11","R12");
$names = array("Robert","John","Steve","Joe","Eddie","Gotham");
$maxLength = count($code) > count($names) ? count($code) : count($names);
for($i = 0; $i < $maxLength; ++$i){
echo array_key_exists($i, $code) ? 'The Code is '. $code[$i] : "";
echo array_key_exists($i, $names) ? ' The Name is '. $names[$i] : "";
echo "<br />";
}
Output:
The Code is R9 The Name is Robert
The Code is R10 The Name is John
The Code is R11 The Name is Steve
The Code is R12 The Name is Joe
The Name is Eddie
The Name is Gotham
i have this array which i retrieved data from my database and put it in an array :
$query = "select * from caseunder";
$result=mysql_query($query) or die('Error, insert query failed');
$array[] = array();
$numrows=mysql_num_rows($result);
WHILE ($i < $numrows){
$allergies =mysql_result($result, $i, "allergies");
$vege = mysql_result($result,$i, "vege");
$age = mysql_result($result, $i, "age");
$bmi =mysql_result($result, $i, "bmi");
$solution = mysql_result($result,$i, "solution");
$bmi2 = $_POST['weight'] / (($_POST['height']/100)*($_POST['height']/100));
if($_POST['age']>18 && $_POST['age']<35)
$age2 = 'young ';
if($_POST['age']>40 && $_POST['age']<50)
$age2 = 'middle age ';
if($_POST['age']>60)
$age2 = 'old men ';
$array[] = array('age'=>$age2,'allergies'=>$allergies,'vege'=>$vege,'bmi'=>$bmi2,'solution'=>$solution);
i++
}
Then, i want to compare each element in that array with input i entered and calculate sum for each row of array :
foreach($array as $cases) {
if($cases['allergies'] == $_POST['allergies']){
$count = 1;
}
if($cases['vege'] == $_POST['vege']){
$count1 = 1;
}
if($cases['bmi'] == $bmi2)
$count2 = 1;
if($cases['age'] == $age2)
$count3 = 1;
$sum = $count + $count1 + $count2 + $count3;
echo $sum;
}
Lets say i have entered age,bmi, allergies and vege which is all are the same like first row of database, the the total sum that should be output is 4 because 4 same comparison of data. In this case that i try, every row of database should have different total sum because its not all the same.But i did not get the output that i want, this is the example of the wrong output:
0
4
4
4
4
4
4
4
4
(assuming i have 8 rows of database in my phpmyadmin)
The first row of database after compared manually the sum is 4 but it seems like when it continue looping the next row take the same amount as prev row.
When you do this loop:
foreach($array as $cases) {
if($cases['allergies'] == $_POST['allergies']){
$count = 1;
}
if($cases['vege'] == $_POST['vege']){
$count1 = 1;
}
if($cases['bmi'] == $bmi2)
$count2 = 1;
if($cases['age'] == $age2)
$count3 = 1;
$sum = $count + $count1 + $count2 + $count3;
echo $sum;
}
You are not resetting the $count, $count1, etc. variables between iterations. That is why
when it continue looping the next row take the same amount as prev
row.
I would say you probably don't even need these separate variables unless you are using them for something else that isn't included in the question. You can just initialize sum to zero for each repetition, then increment it directly if the conditions match.
foreach($array as $cases) {
$sum = 0;
if($cases['allergies'] == $_POST['allergies']){
$sum++;
}
if($cases['vege'] == $_POST['vege']){
$sum++;
}
if($cases['bmi'] == $bmi2) {
$sum++;
}
if($cases['age'] == $age2) {
$sum++;
}
echo $sum;
}
Incidentally, it looks like the way you are setting bmi and age in the first loop will make those values always match. I'm not sure if that's what you intended, but it seems kind of unlikely.
This is wrong:
foreach($array as $array)
You take the multi-dimensional array, which goes by the name $array, and iterate over each item in it, which is also assigned to $array. This is asking for weird behavior. Use a different variable. Array variables don't have to be named $array.
// Start variable sum
$sum = 0:
// For each $_POST[] in array
foreach($_POST as $key => $value){
// If Key in $_POST exists add sum
if(array_key_exists($key,$array)){
++$sum;
}
}
echo $sum;
I did not want to ask, but I am still quite new to PHP and I am stuck.
I have a comma separated list stored in MySQL; Blue, 12, Red, 15 etc.
I can bring it out and do most of what I want, but I am confused on how to proceed.
Ultimately, I would like to change the output of the data from
Blue, 12, Red, 15,
to
Blue => 12, Red => 15 (without the last comma) So I can use the data in a program I am attempting to build.
Currently, I am able to achieve:
Blue, => 12, => Red, => 15,
Code:
$result = $con->query($sql);
if ($result->num_rows > 0) {
while($row = $result->fetch_assoc()) {
$id = $row['id'];
$type = $row["dataname"];
$datas = $type;
eval( "\$test = array (" . $datas . ");") ;
foreach($test as $test)
{
echo "<option name='$test'>$test , =></option>";
}
}
}
Using the desired output, I will be able to input data from a form to create an SVGGraph.
Thank you in advance for any assistance.
Ok so first off, I would try storing this information in separate rows in the future, comma separated lists are for when we do not have databases (simple text files for example).
But to answer your question (assuming result is the string of separated values):
$result = explode(',', $result);
$output = [];
for($i = 0;$i < count($result);$i=$i+2){
array_push($output, $result[i] => $result[i+1]);
}
//output:
$str = ""
foreach($output as $key => $value){
str .= $key . ' => ' . $value . ' ,';
}
$str = rtrim($str, ',');
echo $str //this will be your output
using eval is just the worst.
Here is how I would do it while keeping to your code as much as possible:
$result = $con->query($sql);
if ($result->num_rows > 0) {
while($row = $result->fetch_assoc()) {
$id = $row['id'];
$type = $row["dataname"];
$datas = $type;
$res = array();
$arr = explode(",", str_replace(" ","",$datas));
for ($i = 0; $i < count($arr); $i+=2) {
$res[$arr[$i]] = $arr[$i + 1];
}
foreach($res as $key=>$value)
{
echo "<option name='$value'>$key , =></option>";
}
}
}
First of all, try not to use eval - it is dangerous.:)
Second, try to get all the data you need into one big string. Then you can use the explode PHP function to convert the string into individual elements. And the last thing you would do is to simply iterate over the array and assign the first item as a key and the second item as an element into yet another array.
I will leave the actual implementation to you as an excercise in your PHP coding skills.:)
//trim comma from the right
$str = rtrim('Blue, 12, Red, 15,', ',');
//create a helper array
$array = explode(', ', $str);
//arrange elements in the new array
for ($i = 0; $i < count($array) - 1; $i = $i + 2) {
$new[] = $array[$i] . ' => ' . $array[$i + 1];
}
//output new elements
echo implode(', ', $new);
Please dont use eval. You nearly always can avoid it and is dangerous.
Here is a solution which works without eval:
$result = $con->query($sql);
if ($result->num_rows > 0) {
while($row = $result->fetch_assoc()) {
$id = $row['id'];
$type = $row["dataname"]; // Thats our comma-seperated list, right?
$arr = explode(',', $type); // Make $type to array
array_pop($arr); // Delete last element because its empty
// We go through the array with step = 2
// because the first is always the key and the second the value
for($i = 0; $i < count($arr); $i += 2)
{
echo "<option name='$arr[$i+1]'>$arr[$i] , =></option>";
}
}
}
Why eval is evil:
Whatever is in the string is evaled as code from your script with all rights the script has incuding file-access and so on. Since the string for your eval comes from the database you cant even be absolutely sure that it is no bad code you are executing when using eval.
Furthermore eval is bad when it comes to debugging things.
And at the end: Why producing overhead with stuff you can avoid?
It is in general recognized as bad style when using eval because of all this reasons. Better you never get used to it
If I understand correctly, you go from a string to an array to a string.
If so, it is possible to skip the array by using regex. Depending on the length of your string, creating a huge array may be a problem.
So I came up with those examples:
$input = "Blue, 1, Red, 2, Green, 3, Violet, 4,";
// Output: Blue => 1, Red => 2, Green => 3, Violet => 4
echo rtrim(preg_replace('/(([^,]*),([^,]*)),+/', '\2 =>\3,', $input), ',');
// Output <option name="Blue">Blue => 1</option><option name="Red">Red => 2</option><option name="Green">Green => 3</option><option name="Violet">Violet => 4</option>
echo preg_replace('/(\s*([^,]*)\s*,\s*([^,]*)\s*),+/', '<option name="\2">\2 => \3</option>', $input);
As you can see, no looping involved.
I hope it helped
EDIT
Here is links to visualize the regex
First regex
Second regex
I can only imagine that this is fairly simple, and yet the solution eludes me.
Let assume I have the following variables:
$group1 = "5";
$group2 = "1";
$group3 = "15";
$group4 = "3";
$group5 = "7";
$group6 = "1";
$group7 = "55";
$group8 = "0";
$group9 = "35";
I want the groups listed with the highest amount first e.g.:
Group 7 is number 1 with 55.
Group 9 is number 2 with 35.
Group 3 is number 3 with 15.
Group 5 is number 4 with 7.
Group 1 is number 5 with 5.
Group 4 is number 6 with 3.
Group 2 is number 7 with 1.
Group 6 is number 8 with 1.
Group 8 is number 9 with 0.
Perhaps it would be easier to list all the data in a double-array and then sort it?
First of all, use arrays(just usual arays).
If you array is
$group = array(1 => 5, 2 => 1 ... )
You may use arsort function.
Here I use numbers, not strings. If you will use strings (for values) you need a flag for sort (SORT_NUMERIC)
More information in PHP Manual
Then use foreach
foreach($group as $key => $value){
$key is number of varaiable
$value is value of it.
you also may add counter to print 1,2,3...
}
use arrays for this purpose
$group[1] = "5";
$group[2] = "1";
$group[3] = "15";
$group[4] = "3";
$group[5] = "7";
$group[6] = "1";
$group[7] = "55";
$group[8] = "0";
$group[9] = "35";
and then sort it.
arsort($group, SORT_NUMERIC); // SORT_NUMERIC suggested by **fab**
Just have your data inside an associative array, and sort it with an association aware sort:
$groups = array(
'group1' => "5",
'group2' => "1",
'group3' => "15",
'group4' => "3",
'group5' => "7",
'group6' => "1",
'group7' => "55",
'group8' => "0",
'group9' => "35",
);
arsort($groups);
// iteration as usual
foreach ($groups as $group_name => $value) {
}
// getting elements with the array functions based around the array's internal pointer
reset($groups); // reset the pointer to the start
print key($groups); // the first element's key
print current($groups); // the first element's value
next($groups); // moving the array to the next element
Yes using an array is the best thing to do.
something like that
$group[1]="5";
$group[2]="1";
After that you can sort your array
The best way to do this is with an array and arsort. This will keep your indexes intact.
arsort returns a boolean so do not assign to a new variable
$groups = array("5","1","15","3","7","1","55","0","35");
arsort($groups, SORT_NUMERIC);
$i = 1;
foreach ($groups as $key => $val) {
echo 'Group ' . $key . ' is number ' . $i . ' with ' . $val;
$i++;
}
Put your groups in an array
$groups = array("5","1","15","3","7","1","55","0","35");
arsort($groups); //This sort the array is descending order
var_dump($sorted_groups);
To print the array in your format use the following function
count = 1;
foreach($groups as $key => $value) {
echo "Group ".($key+1)." is number ".$count++." with ".$value;
}