I have an array filled with the result of a query which is as follows:
$ticket[] = array(
'ticket_id' => $row->ticket_id,
'user_id' => $row->user_id,
'raffle_ticket_num' => $row->raffle_ticket_num
);
Now, in a while loop, I check in all arrays inside $tickets if my variable $number equals 'raffle_ticket_num'. I do this with the following code (from #Fuzzy Tree):
$ticket_num=1;
while ($ticket_num <= $total_slots){
foreach($ticket as $test) {
if($test['raffle_ticket_num'] == $ticket_num) {
echo $ticket_num.' claimed by '.$test['user_id'];
}
else{
echo $ticket_num;
}
}
$ticket_num++;
}
The problem that I'm having now is that because I'm using a foreach loop, if more than one results are found, it causes it to echo each result as much as there are rows in $ticket[]... So with 2 rows it echos everything 2 times (because of the foreach). Does anyone know a solution or alternatives for this?
You can see it live here: http://tinyurl.com/hxbhx7y .The bold numbers are slot 21 and 38 which are taken and showing the user_id (1). But as you can see it shows each number 2 times (because foreach has 2 results)
EDIT: Post updated with #Fuzzy Tree's answer
Version 1
foreach see answer by #FuzzyTree
Version 2
array_filter
$number = 1;
$winners = array_filter($tickets, function ($ticket) use ($number) {
return $ticket['raffle_ticket_num'] == $number;
});
// $winners now has all winning tickets.
var_dump($winners);
// Bonus pick a random winner
shuffle($winners);
var_dump(current($winners));
So best and easiest way to do it prepare your tickets array outside of raffles loop.
Solution
<?php
$tickets[] = array(
'ticket_id' => 1,
'user_id' => 2,
'raffle_ticket_num' => 15
);
$tickets[] = array(
'ticket_id' => 2,
'user_id' => 2,
'raffle_ticket_num' => 25
);
$tickets[] = array(
'ticket_id' => 3,
'user_id' => 1,
'raffle_ticket_num' => 21
);
$raffles = range(1, 50);
// Preparing tickets array. Now when I think Flattened is not the best word to describe it :)
$ticketsFlattened = array();
foreach ($tickets as $ticket) {
$ticketsFlattened[$ticket['raffle_ticket_num']] = $ticket;
}
// Could be while if you want
foreach ($raffles as $number) {
if (array_key_exists($number, $ticketsFlattened)) {
echo sprintf(
"Ticket %s is clamed by %s, ticket id %s %s",
$number,
$ticketsFlattened[$number]['user_id'],
$ticketsFlattened[$number]['ticket_id'],
PHP_EOL
);
} else {
echo sprintf("Ticket %s unclaimed %s", $number, PHP_EOL);
}
}
If you need to print the matching user_id and ticket_id then use a foreach to check each ticket one by one and when you see a ticket with the matching #, you can print the other details
foreach($tickets as $ticket) {
if($ticket['raffle_ticket_num'] == $number) {
print 'In array';
print $ticket['user_id'];
print $ticket['ticket_id'];
//break; //uncomment if you just want one
}
}
Related
I'am just trying to pass a special value for my array in CONTROLLER where this value will be effect only for the first item in the foreach loop. I know how to implement this in view ($loop ->first) . But this can't be used inside a controller.
I have a table with prices where this table contain both $ and £. So what I'm doing is all the values in the table will be loop through the foreach loop and I'm currently adding few more items in to array with some if conditions. Please refer below code.
$sortAccordingToPrice = [];
foreach($listings as $dbValues){
if(($dbValues['ref'] == ConstatntE::E['id'] ) ) {
$newPrice = array(
'converted_price' => $dbValues["price"] * Session::get('LRK') ,
'id' => $dbValues["id"],
'seller_logo' => $dbValues['APT']["RFL"],
'ref' => $dbValues['ref'],
);
array_push($sortAccordingToPrice , $newPrice);
}else{
$newPrice = array(
'converted_price' => $dbValues['APT']["price"],
'id' => $dbValues["id"] ,
'seller_logo' => $dbValues['APT']["RFL"],
'ref' => $dbValues['ref']
);
array_push($sortAccordingToPrice , $newPrice);
}
}
So what I wants to do is to add 'isLowest' => TRUE only for the first element of the both if conditions. Means if first if statement true then 'isLowest' => TRUE will be added to the array for the first time and when the second if condition gets true 'isLowest' => TRUE also will be included into the array.
Please note I'm not asking in the .blade.php I wants to do this in the Controller
Type:1 you may use array_key_first
foreach($listings as $key => $dbValues){
if ($key === array_key_first($listings)){
echo 'FIRST ELEMENT!';
}
}
Type:2 you may use the key as well.
foreach($listings as $key => $dbValues){
if ($key === 0){
echo 'FIRST ELEMENT!';
}
}
Type: 3 The first time you'll get true then it'll be false.
$first = true;
foreach ($listings as $key => $value)
{
if ( $first )
{
// do something
$first = false; //in order not to get into the if statement for the next loops
}
else
{
// do something else for all loops except the first
}
}
Use the other syntax for a foreach loop
foreach($listings as $idx => $dbValues){
then inside the loop you can code
if( $idx == 0 ) {
// the first time round the foreach loop
// do whatever is required only on the frst time round the loop
I am doing a simple shopping application were user may choose books from the store based on the title, price, quantity etc. At the moment all details of the books are kept in an associative array which looks like this:
$menu = array(
array ('id' => '1', 'catagory' => 'newbooks','title' => 'Alex','price' => 4.95, 'desc' => 'bbbb'),
array('id' => '2','catagory' => 'newbooks','title' => 'David ','price' => 5.95, 'desc' => 'sss'),);
}
What I am trying to achieve is merge or remove duplicated entries of book id's also each book title will be printed in one single row containing 'title', 'id', 'price'
for example:
Alex qty:2 price 4.95
David qty:2 price 5.95
and so on...
And this is my cart file:
$buy = array();
$qty = 0;
$total = 0;
foreach ($_SESSION['buy'] as $id) {
foreach ($menu as $book ) {
if ($book['id'] == $id) {
$buy[] = $book;
$total += $book['price'];
}
}
}
}
if (count($buy) > 0)
if (count($book) > 0)
{
echo"<table>";
echo"<tr><th>Item Description</th><th>Quantity</th><th>Price</th></tr>";
foreach ($buy as $book){
$f_price = sprintf("%0.2f", $book["price"]);
echo"<tr><td>" .$book["title"] ."</td>";
echo"<td>" .$qty."</td><";
echo"<td>" .$f_price."</td></tr>";
}
echo"<tr><td>Total</td><td>".$total."</td></tr>";
echo"</table>";
}
I will be extremely grateful for any help or advice cause I spent long long time to resolve this problem trying use unique functions, for statements foreach loop but in vain I am still novice also please try to be a little tolerant . Cheers!
Untested but this should do what you want using array_count_values to obtain the quantities you were looking for along with a few changes to make the script more efficient and easier to manage.
<?php
//the ids of the items the user wants to buy
$ids=$_SESSION['buy'];
//Your database of items
$menu = array(
array ('id' => '1', 'catagory' => 'newbooks','title' => 'Alex','price' => 4.95, 'desc' => 'bbbb'),
array('id' => '2','catagory' => 'newbooks','title' => 'David ','price' => 5.95, 'desc' => 'sss')
);
//Create a reverse look-up for the database
$lookUp=array();
foreach($menu as $i=>$v)$lookUp[$v['id']]=$menu[$i];
//populate the cart with items, their quantities, and a total
$cart = array();
$total = 0;
foreach (array_count_values($ids) as $id=>$quantity)
{
if (!array_key_exists($id, $lookUp))continue;
$item=$lookUp[$id];
$itemTotal=$item['price']*$quantity;
$total+=$itemTotal;
$cart[]=array_merge($item,array('quantity'=>$quantity,'itemTotal'=>$itemTotal));
}
if(count($cart) > 0)
{
echo '<table>';
echo '<tr><th>Item Description</th><th>Quantity</th><th>Price</th><th>Item Total</th></tr>';
foreach ($cart as $item)
{
echo sprintf('<tr><td>%s</td><td>%s</td><td>%0.2f</td><td>%0.2f</td></tr>',
$item["title"],$item['quantity'],$item['price'],$item['itemTotal']);
}
echo '<tr><td colspan="3" style="text-align:center;">Total</td><td>'.$total.'</td></tr>';
echo '</table>';
}
If it's just based off the id, when you build the array, store the book id as the key in the larger array, so your end array would be:
$books = array(
1=> array ('id' => '1', [...]),
2=> array ('id' => '2', [...])
);
You could also add some code that checks when you try to assign a value to that array to see if the key is already set.
if(!isset($books[$book_id])){
//Add to the array
}else{
//Maybe display an error?
}
PS: Category only has one a in it.
It's a pretty cumbersome way to make a stock overview of the books in your collection, but that aside :)
If i was to work with an array like that, (and i would never do that :)) i would first select all unique keys, and then go through them one by one, counting the number of times it occur in the $menu array.
As follows:
$unique_books = array_unique($menu);
foreach($unique_books as $book){
$qty = array_keys($menu, $book["id"])
$book["qty"] = $qty;
$stock = $book;
}
As you can see, now $stock will be the unique array, with a qty added to it, containing the number of times, the id was seen in $menu.
This is just a fast code block, and should be testet, but the theory works i think. As i mentioned before, the way you'r making this in the first place, is not very smart, and you should really reconsider the whole thing imo :)
If you don't wanna duplicates simple use the book_id as the key of buy array
Example:
$menu = array(
array('id' => '1', 'catagory' => 'newbooks','title' => 'Alex','price' => 4.95, 'desc' => 'bbbb'),
array('id' => '2','catagory' => 'newbooks','title' => 'David ','price' => 5.95, 'desc' => 'sss')
);
$session=array(1,2,2,2,1);
$buy = array();
foreach ($session as $id) {
foreach ($menu as $book) {
if ($book['id'] == $id) {
if(isset($buy[$id])){
$buy[$id]['qty']++; // increase quantity
$buy[$id]['total'] += $book['price']; // total price only for this id
$buy['total'] += $book['price']; // All ids price total
}else{
$buy[$id] = $book; // assign new id to the buy array
$buy[$id]['qty'] = 1; // quantity reset to 1
$buy[$id]['total'] = $book['price']; // id price
$buy['total'] += $book['price']; // total price
}
}
}
}
print_r($buy);
You can test it here!
http://codepad.org/wH2WskLG
Instead of merging duplicates you should add book id and qty as array row to session.
On session start..
if (!isset($_SESSION['buy']))
$_SESSION['buy'] = array();
When adding new..
$new_book = $added_book; // just for example
$qty = $added_qty; // Added qty
// Check if book already exists in shopping cart and update qty
if (array_key_exists($new_book['id'], $_SESSION['buy'])) {
$_SESSION['buy'][$new_book['id']] += $qty;
} else {
$_SESSION['buy'][$new_book['id']] = $qty;
}
Then on shopping cart view just loop thru your items..
foreach($menu as $book ) {
if (array_key_exists($book['id'], $_SESSION['buy'])) {
// User bought this book..
$qty = $_SESSION['buy'][$book['id']];
}
}
I have a list of nested items (categories) I would like to reorganize, by ordering and nesting depth. I will try to explain:
When I submit a form with jQuery by clicking on blue button SAVE, it process a function inside models/categories_model.php:
public function organize($items){
if( count($items)){
foreach($items as $order => $item){
if($item['item_id'] != ''){
echo '<pre>'.$order.'</pre>';
$data = array(
'pid' => (int) $item['parent_id'],
'ordering' => $order
);
$this->db
->set($data)
->where($this->_primary_key, $item['item_id'])
->update($this->_table_name);
}
}
}
}
It saves that list like this:
1
2
3
4
5
6
7
8
9
10
Instead of saving it like this:
1
1
2
3
4
2
1
2
3
1
2
1
2
3
3
Instead of getting $order value one by one, it should take into the account it's nested items and start counting the $order from 1, and not continuing a counting from it's parent item.
So when I save it, I want them to be ordered like this, but don't know how to do it:
Someone know how to make it work with nested items pls?
If method recieves items in correct order, this should work:
public function organize($items)
{
if (!empty($items)) {
$orderByPid = array();
foreach ($items as $item) {
if($item['item_id'] != '') {
if (!isset($orderByPid[$item['parent_id']])) {
$orderByPid[$item['parent_id']] = 0;
}
$data = array(
'pid' => (int) $item['parent_id'],
'ordering' => ++$orderByPid[$item['parent_id']]
);
$this->db
->set($data)
->where($this->_primary_key, $item['item_id'])
->update($this->_table_name);
}
}
}
}
I am not sure what should be title of this question, If you have better option, don't hesitate to change.
I need to search in an array with team's full name and return the short name. Now I have the following creteria:
$teams = array('MMB' => 'Mumbai', 'MMB' => 'Mumbai Indians');
$Vteam = (array_search($vteam, $teams, true) !== false) ? array_search($vteam, $teams) : substr($vteam, 0, 3);
When I search for 'Mumbai Indians', it returns 'MMB', but when I search for 'Mumbai' alone it returns 'Mum'.
I have around 50 team names in $team array.
How should I code so that on 'Mumbai' and 'Mumbai Indians' search it returns me 'MMB' always?
Any help would be really appreciated.
If you're creating the $teams array by yourself, then form it properly with an array for the values!
$teams = array('MMB' => array( 'Mumbai', 'Mumbai Indians'));
However, if you want a lookup of the short name, invert this design:
$teams = array( 'Mumbai' => 'MMB', 'Mumbai Indians' => 'MMB');
Now, if you want to know Mumbai's short name, just index the array on their name:
echo $teams['Mumbai']; // Output: MMB
echo $teams['Mumbai Indians']; // Output: MMB
If you are doing partial match you will probably need to use a foreach loop:
$search = 'Mumbai';
$team = '';
foreach($teams as $shortname => $longname) {
if(strpos($longname,$search) !== false) {
$team = $shortname;
break;
}
}
I have an array of posts that I want to sort - but before I do, I want to find the id of the post with the highest number of likes.
I loop through the array using a foreach. Although it seems like a waste to do two foreach loops for this - I don't know if there's an alternative when trying to find the highest value beforehand?
Array
(
[0] => Array
(
[id] => 162
[like_count] => 2
etc.
)
[1] => Array
(
[id] => 165
[like_count] => 23
etc.
)
)
So the second post has the highest amount of likes, so I need the ID of 165 - then when I loop through I can do something like
foreach ($posts as $post){
if($most_liked_id == $post["id"]){
// this post is the most liked!
}
}
Any help would be much appreciated - thanks!
$highest = 0;
$highest_id = 0;
foreach($array as $a) {
if($a['like_count'] > $highest) {
$highest = $a['like_count'];
$highest_id = $a['id'];
}
}
Hope I understood you correctly :)
This looks like data retrieved from a database. If so, use the ORDER BY like_count DESC clause in the SQL.
The ID of the post with the most likes will then be at $posts[0]['id'] before you sort by your other method.
very easy task, you loop through your posts.
function get_max_like_post($posts) {
$max_like = 0;
$max_like_post = array();
foreach ($posts as $post) {
if ($post['like_count'] > $max_like) {
$max_like = $post['like_count'];
$max_like_post = $post;
}
}
return $max_like_post['id']
}
You could use usort.
$posts = array(
array('id' => 161, 'like_count' => 0),
array('id' => 162, 'like_count' => 6),
array('id' => 4, 'like_count' => 2),
);
function like_sort($a, $b) {
if ($a['like_count'] == $b['like_count']) {
return 0;
}
return ($a['like_count'] > $b['like_count']) ? -1 : 1;
}
usort($posts, 'like_sort');
// The first element in the array is now the one with the highest like_count.
echo $posts[0]['id']; // 162
Try this:
usort($posts, function($item) { return -$item['like_count']; });
$id = empty($posts) ? null : $posts[0]['id'];
Where $posts is the input array.
Explanation:
first you sort the posts by like count in decreasing fashion
then you get the top post id if there any posts, null otherwise.
What's good about this solution is that you can also select first n posts.
$highest_post_likes = 0;
$highest_post_id = 0;
for($i = 0; $i < sizeof($posts); $i++) {
if ( $posts[$i][like_count] > $highest_post_likes ) {
$highest_post_likes = $posts[$i][like_count];
$highest_post_id = $i;
}
}
// now you can use $posts[$highest_post_id]
Is those datas came from a database like MySQL? If is it, the simpliest solution is to put an "ORDER BY".
You can also make seperate the 'like_count' array keeping the same key than your first array and doing a asort (http://www.php.net/manual/fr/function.asort.php). You will have the key of the highest like count.
You can sort the array in descending order based on like_count and then pick up the id for the first array element.
You can use max function to get the highest value of likes:
foreach ($posts as $post){
$max[]=$post['like_count'];
}
echo max($max['id']);