Get Number and Name From Array PHP - php

I've created an array that contains the elements of an order:
Array ( [0] => M8 [1] => M8 [2] => U- )
(it gets the first 2 chars from the title in the foreach loop - its all i need)
I need to know how many M8's come up in this array.
basically if they buy 2 or more M8's then they get a free item. But if they buy 1 M8 and a U- they get nothing.
There will also be other products too:
Array ( [0] => M8 [1] => M8 [2] => U- [3] => D8)
if they buy an M8 and a D8 they get a free item as well
so its not just based off quantity its based off how many items they buy and the product ID (m8,d8 ect..)
a free item with any d8 and m8 purchase, or free item with any 2 d8 or and 2 m8
thanks.

There's a function for that:
http://us3.php.net/manual/en/function.array-count-values.php
Should return an array like array('M8' => 2, 'U-' => 1, etc. etc.)
Edit: For example.
<?php
$counts = array_count_values($input);
if(isset($counts['M8']) && $counts['M8'] >= 2)
{
//Do special things when 2 M8's are present.
}

Related

PHP / MySQL / Jquery - Building associative array and outputing it using JQuery $.each

I'm building a calendar (FullCalendar) that shows orders for each day and the items that were ordered when you click on an order. When $order_info is put into the $data array, it's missing certain rows of data, as shown below in the 4th code block down. I'm trying to figure out how to put the array together so that every description (key) that is supposed to be shown is paired with the correct quantity (value) and then iterated out using an $.each function in jquery.
The $desc & $qty variables are concatenated when I query them from my table so I'm using the explode function to separate their values.
foreach($sql_query as $row) {
$desc = array_map('trim', explode(',', $row['OlineDesc']));
$qty = array_map('trim', explode(',', $row['OlineQty']));
$order_info = array_combine($desc, $qty);
$data[] = array (
'start' => $row['OrderDate'],
'order_id' => $row['OrderID'],
'desc_qty' => $order_info
);
}
Printing out the array after the closing tag of the foreach:
echo "<pre>";
echo print_r($data);
echo "</pre>";
Output:
// Output when print_r($data)
[0] => Array
(
[start] => 2019-05-11 16:00:00
[order_id] => 2509
[description] => Time: 04:00PM
[desc_qty] => Array
(
[#4 Beef and Pizza Special] => 1
[6 Lbs Italian Beef] => 1
[**incl Brd + Au Jus] => 1
[**incl Sweet Peppers] => 1
[**incl Hot Giardiniera] => 1
[XL 18" Pizza] => 1
[SAUSAGE] => 1
)
)
If I use array_merge to join my arrays instead of array_combine, it merges all the keys and values together as all the keys first, then values... but it's at least showing every row as opposed to the limited # of rows:
$order_info = array_merge($desc, $qty);
// Output when print_r($order_info)
[desc_qty] => Array
(
[0] => #4 Beef and Pizza Special
[1] => 6 Lbs Italian Beef
[2] => **incl Brd + Au Jus
[3] => **incl Sweet Peppers
[4] => **incl Hot Giardiniera
[5] => XL 18" Pizza
[6] => SAUSAGE
[7] => XL 18" Pizza
[8] => XL 18" Pizza
[9] => 1
[10] => 1
[11] => 1
[12] => 1
[13] => 1
[14] => 1
[15] => 1
[16] => 1
[17] => 1
)
Then I'm using jquery that's bound to an onClick event to load the information into a div where key is the description of the item and the value is the quantity:
$.each( event.desc_qty, function( key, value ) {
document.getElementById("party_info").innerHTML += "<span class="+key+">" + key + "<span id='sum_"+key+"'>" + value + "</span></span>";
});
My codes current output:
#4 Beef and Pizza Special 1
6 Lbs Italian Beef 1
**incl Brd + Au Jus 1
**incl Sweet Peppers 1
**incl Hot Giardiniera 1
XL 18" Pizza 1
SAUSAGE 1
Expected output that I'm trying to achieve:
#4 Beef and Pizza Special 1
6 Lbs Italian Beef 1
**incl Brd + Au Jus 1
**incl Sweet Peppers 1
**incl Hot Giardiniera 1
XL 18" Pizza 1
SAUSAGE 1
XL 18" Pizza 1
XL 18" Pizza 1
Any help or direction would be much appreciated! Thanks!
EDIT:
This is my SQL query. I'm using 3 different tables to gather all my information where I match the ID's to pull the proper information.
SELECT a.OrderDate, a.OrderID, a.OrdCustName, a.OrdPhone, b.OtotOrder,
b.OtotTotal, c.OlineOrder, GROUP_CONCAT(c.OlineDesc SEPARATOR ',') as
'OlineDesc', GROUP_CONCAT(FLOOR(COALESCE(c.OlineQty,'1'))) as
'OlineQty'
FROM db.tbldeferredorders a, db.tbldeferredordtotals b,
db.tbldeferredordlines c
WHERE a.OrderID = b.OtotOrder AND a.OrderID = c.OlineOrder
AND a.OrderDate >= NOW() - INTERVAL 3 MONTH
GROUP BY a.OrderID
This query will pull the OlineDesc column into a concatenated string that looks like this. Each comma is from a separate row that I pull together based on a.OrderID. So for this particular row, the OrderID is '2536'.
'#4 Beef and Pizza Special,6 Lbs Italian Beef,**incl Brd + Au
Jus,**incl Sweet Peppers,**incl Hot Giardiniera,XL 18" Pizza,XL 18"
Pizza,SAUSAGE,XL 18" Pizza,PEPPERONI,Lrg Caesar Salad,** ceaser
dressing,Lg 3 Cheese Baked Penne'
The OlineQty column looks like this when I run the query:
'1,1,1,1,1,1,1,1,1,1,1,1,1'
It's probably not the most elegant solution but I found a way to solve my issue. I found that array_combine can't have duplicate keys, so instead of having just a single array, I decided on having 2. And since both arrays have an equal number of descriptions to quantities, I took the descriptions array and used an $.each loop to go through it, then I paired it with the qty[key] as it was going through each loop. This matched it line for line.
$.each( event.desc, function( key, value ) {
document.getElementById("party_info").innerHTML += "<span class="+value+">" + key + "<span id='sum_"+value+"'>" + event.qty[key] + "</span></span>";
});

PHP Need Help In Sub Array

I have a two table 1. grocery_product and 2. grocery_attribute where i can get all data from grocery_product my array look like as below.
Array
(
[0] => Array
(
[id] => 1
[pname] => Royal Moong Dal/Moong Dal
[categoryid] => 4
[subcatid] => 3
[added_date] => 2016-08-16
)
[1] => Array
(
[id] => 2
[pname] => Royal Toor Dal/Arhar Dal/Tuver Dal
[categoryid] => 4
[subcatid] => 3
[added_date] => 2016-08-16
)
)
What i want to do that in my grocerry_attribute table i am passing grocery_product_id and fetch all data from grocery_attribute where product is only one and attributes are multiple.
My grocery atrtribute table look like .
id 1
product_id 2
price 1500
discount 15
product_qty 20
id 2
product_id 2
price 1000
discount 10
product_qty 50
i want to fetch one grocery_product(id=1) and its attribute data.
Query ??
You can use LEFT JOIN like,
SELECT p.id,p.pname,g.price,g.discount,g.product_qty FROM
grocery_product as p
LEFT JOIN grocery_attribute as g
ON p.id = g.product_id
WHERE p.id=2
Now you can loop for attributes and show different price, discount, and product_qty for a single product.
// Let $products is multidimensional array
if(!empty($products) && isset($products[0]['pname'])){
echo '<h1>'.$products[0]['pname'].'</h1>';
foreach($products as $product){
echo 'Price:'.$product['price']."\n";
echo 'Discount:'.$product['discount']."\n";
echo 'Product Quantity:'.$product['product_qty']."\n";
}
}

PHP: calculate popularity/frequency of an item sold from multimensional Array

I have an array extracted from my mysql that stores item_id, day that the item_id has been sold or not sold, and the price
my query is something like
select * from freq_history_sales
where freq_item_id = 123
and the output example is given below
[0] => Array
(
[freq_item_id] => 123 // item ID / sku number etc..
[freq_end] => 2016-05-06 // when the sale ended
[freq_status] => sold // if sold or not
[freq_price] => 175 // price sold
)
[1] => Array
(
[freq_item_id] => 123
[freq_end] => 2016-05-06
[freq_status] => notsold
[freq_price] => 225
)
[2] => Array
(
[freq_item_id] => 123
[freq_end] => 2016-05-10
[freq_status] => notsold
[freq_price] => 225
)
...etc...
I would like to record the time, sold/not sold on that specific day, and final price or items and then calculate a sort of frequency/popularity of this item
I am asking if this is something that can be done in PHP. I that is the case, how to transform that frequency in a sort of index 1 to 10 so that I can judge the popularity.

php mysql check if vendor has 3 low consecutive ratings

on my ratings table for my software i have 4 fields.
id autoincrement
rvid vendor id
ratedate date of rating
rating the actual numeric rating
I have done alot with it over the last few months but this time im stumped and i cant get a clear picture in my head of the best way to do this. What i am trying to do is find out if the vendor has had 3 low 'consecutive' ratings. If their last three ratings have been < 3 then i want to flag them.
I have been playing with this for a few hours now so i thought i would ask (not for the answer) but for some path direction just to push me forward, im stuck in thought going in circles here.
I have tried GROUP BY and several ORDER BY but those attempts did not go well and so i am wondering if this is not a mysql answer but a php answer. In other words maybe i just need to take what i have so far and just move to the php side of things via usort and the like and do it that way.
Here is what i have so far i did select id as well at first thinking that was the best way to get the last consective but then i had a small breakthrough that if they have had 3 in a row the id does not matter, so i took it out of the query.
$sql = "SELECT `rvid`, `rating` FROM `vendor_ratings_archive` WHERE `rating` <= '3' ORDER BY `rvid` DESC";
which give me this
Array
(
[0] => Array
(
[rvid] => 7
[rating] => 2
)
[1] => Array
(
[rvid] => 5
[rating] => 1
)
[2] => Array
(
[rvid] => 5
[rating] => 0
)
[3] => Array
(
[rvid] => 5
[rating] => 3
)
)
this is just just samples i tossed in the fields, and there are only 4 rows here where as in live it will be tons of rows. But basically this tells me that these are the vendors that have low ratings in the table. And that is where i get stumpted. I can only do one sort in the query so that is why i am thinking that i need to take this and move to the php side to finish it off.
I think i need to sort the elements by rvid with php first i think, and then see if three elements in a row are the same vender (rvid).
Hope that makes sense. My brain hurts lol...
update - here is all of the table data using *
Array
(
[0] => Array
(
[id] => 7
[rvid] => 7
[ratedate] => 2016-05-01
[rating] => 2
)
[1] => Array
(
[id] => 8
[rvid] => 5
[ratedate] => 2016-05-01
[rating] => 1
)
[2] => Array
(
[id] => 6
[rvid] => 5
[ratedate] => 2016-05-01
[rating] => 0
)
[3] => Array
(
[id] => 5
[rvid] => 5
[ratedate] => 2016-05-01
[rating] => 3
)
)
Here's one way you can begin approaching this - completely in SQL:
Get the last rating for the vendor. ORDER BY date DESC, limit 1.
Get the second to last rating for the vendor. ORDER BY date DESC, limit 1, OFFSET 1.
Then write a query that does a LEFT join of the first two tables. You will have a dataset that has three columns:
vendor id
last rating
second to last rating
Then you can write an expression that says "if column1 is <3 and column2 < 3, then this new column is true"
You should be able to extend this to three columns relatively easily.
Here is what a came up with to solve this riddle. I think explaining it on here helped as well as Alex also helped as he keyed my brain on using the date. I first started looking at using if statment inside of the query and actually that got my brain out of the box and then it hit me what to do.
It is not perfect and certainly could use some trimming to reduce the code, but i understand it and it seems to work, so that is par for me on this course.
the query...
$sql = "SELECT `rvid`, `ratedate`,`rating` FROM `vendor_ratings_archive` WHERE `rating` <= '3' ORDER BY `ratedate`, `rvid` DESC";
which gives me this
Array
(
[0] => Array
(
[rvid] => 7
[ratedate] => 2016-05-01
[rating] => 2
)
[1] => Array
(
[rvid] => 5
[ratedate] => 2016-05-01
[rating] => 1
)
[2] => Array
(
[rvid] => 5
[ratedate] => 2016-05-01
[rating] => 0
)
[3] => Array
(
[rvid] => 5
[ratedate] => 2016-05-01
[rating] => 3
)
)
notice how vendor (rvid) 5 is grouped together which is an added plus.
next a simple foreach to load a new array
foreach($results as $yield)
{
$rvidarray[] = $yield['rvid'];
}//close foreach
which gives me this
Array
(
[0] => 7
[1] => 5
[2] => 5
[3] => 5
)
then we count the array values to group dups
$rvidcounter = array_count_values($rvidarray);
which results in this
Array(
[7] => 1
[5] => 3
)
so now vender 7 as 1 low score and vendor 5 has 3 low scores and since they were already sorted by date i know that its consecutive. Well it sounds good anyway lol ")
then we create our final array with another foreach
foreach($rvidcounter as $key => $value)
{
//anything 3 or over is your watchlist
if($value > 2)
{
$watchlist[] = $key; //rvid number stored
}
}//close foreach
which gives me this
Array
(
[0] => 5
)
this was all done in a service function. So the final deal is everyone in this array has over 3 consecutive low ratings and then i just use a returned array back in my normal php process file and grab the name of each vender by id and pass that to the html and print out the list.
done...
please feel free to improve on this if you like. I may or may not use it because the above code makes sense to me. Something more complicated may not make sense to me 6 mos from now lol But it would be interesting to see what someone comes up with to shorten the process a bit.
Thanks so much and Happy Coding !!!!!
Dave :)
You could do it in SQL like that:
SET #rvid = -1;
SELECT DISTINCT rvid FROM
(
SELECT
rvid,
#neg := rating<3, /* 0 or 1 for addition in next line */
#count := IF(#rvid <> rvid , #neg, #count+#neg) AS `count`, /* set or add */
#rvid := rvid /* remember last row */
FROM
testdb.venrate
ORDER BY
rvid, datetime desc
) subq
WHERE count>=3
;
You set a variable to a non existing id. In each chronologically sorted row you check if rating is too low, that results in 1 (too low) or 0 (ok). If rvid is not equal to the last rvid, it means a new vender section is beginning. On begin of section set the value 0 or 1, else add this value. Finally store the current row's rvid for comparison in next row process.
The code above is looking for 3 consecutive low ratings (low means a value less than 3) over all the time.
A small modification checks if all the latest 3 ratings has been equal to or less than 3:
SET #rvid = -1;
SELECT DISTINCT
rvid
FROM
(
SELECT
rvid,
#high_found := rating>3 OR (#rvid = rvid AND #high_found) unflag,
#count := IF(#rvid <> rvid , 1, #count+1) AS `count`,
#rvid := rvid /* remember last row */
FROM
testdb.venrate
ORDER BY
rvid, datetime desc
) subq
WHERE count=3 AND NOT unflag
;

Order array items based on their occurrence desc in php

I have an array of mysql records in $allrecords variable.
There are multiple keys for each record and one of the key is called type.
Some of the variable has the same type.
E.g. it looks like this:
Seat
Mercedes
BMW
BMW
Mercedes
Audi
Mercedes
Fiat
Mercedes
Audi
Fiat
Mercedes
The array is unordered now (just grabbed from database) and now I need to order the array items from the most occurance one to the least.
E.g. like this
Mercedes (5)
Audi (3)
BMW (2)
Fiat (2)
Seat (1)
I do not need the numbers (that I get using another foreach loop), so I need it just like this:
Mercedes
Audi
BMW
Fiat
Seat
How to do such this in PHP? Is it possible? I need to group the items based on the type and then order them from the most to the least occurance.
Thanks in advance.
EDIT:
My array look like this:
Array
(
[0] => stdClass Object
(
[id] => 125
[user_id] => 29
[show] => 1
[state] => 1
[type] => 23
[subcat_id] => 11
[category_id] => 2
[name] => SLK 350
)
)
<?php
$groups = array();
foreach($allrecords as $record){
$type = $record->type;
if(empty($groups[$type]))
$groups[$type] = 1;
else
$groups[$type]++;
}
asort ($groups);
$cars = array_keys($groups);
print_r($cars);
usort($allrecords, function($a, $b){ return $a->count >= $b->count; });
where "count" is the name of the property...
var_dump(str_word_count(implode(" ", $all_records))); // Returns array( "Mercedes" => 5 ... )
aaaah i didn't get that!!!
you should use SQL to achieve this!!!
SELECT type, COUNT(1) FROM cars GROUP BY type;

Categories