PHP Random generator from array issues - php

So I have done some research and fixed most of the issues but I can't find out why this is giving me a Notice: Undefined index: in Line 344
If you guys have any suggestion it would be greatly appreciated :D
Here is my Array:
$quote = array(
1 => array(
"quote" => 'The early bird gets the worm, but the second mouse gets the cheese...',
"name" => 'Stephen Wright'
),
2 => array(
"quote" => 'Your time is limited, so dont waste it living someone elses life.',
"name" => 'Steve Jobs'
),
3 => array(
"quote" => 'When one door closes, another one opens. Or you could jut re-open the closed door. Because thats how doors work.',
"name" => "Anon."
),
4 => array(
"quote" => "The two most important days in your life are the day you are born and the day you find out why.",
"name" => "Mark Twain"
),
5 => array(
"quote" => "Before you criticize someone, you should walk a mile in their shoes, that way when you criticize them, you're a mile away and you have their shoes.",
"name" => "Anon."
),
);
$random=array_rand($quote,1);
And my output:
[This is line 344]
<?php
echo $quote[$random[0]]
?>

If you only get 1 array key with array_rand(), then you don't get an array back, just the key. As you can see in the manual:
When picking only one entry, array_rand() returns the key for a random entry. Otherwise, an array of keys for the random entries is returned. [...]
So after this you try to access the number as an array which doesn't work. So just remove the index from it, e.g.
echo $quote[$random]
//^ See here removed
Since it is a two dimension array you also have to sepcify the second dimesion if you want to use echo to print the value, e.g.
echo $quote[$random]["quote"];
echo $quote[$random]["name"];

Related

Calculations multiple arrays in foreach loop?

I have a database and perform a SQL-request against it to retrieve data. I use a LIMIT statement in my SQL-request to only retrieve eight rows of the SELECT-ed db-data at a time and the DESC-command to sort the data returned in descending order. More data can then be added in the same fashion via a dedicated load-button that performs an ajax-request.
The arrays in my foreach ($result as $data) have the following structure/key-value-pairs.
print_r($data) shows the following:
Array (
[*keyname0*] => group-id
[*keyname1*] => name of 1st-item
[*keyname2*] => state of 1st-item
[*keyname3*] => 93.42
[*keyname4*] => unit of 1st-item
)
Array (
[*keyname0*] => group-id
[*keyname1*] => name of 2nd-item
[*keyname2*] => state of 2nd-item
[*keyname3*] => 93.12
[*keyname4*] => unit of 2nd-item
)
Array (
[*keyname0*] => group-id
[*keyname1*] => name of 3rd-item
[*keyname2*] => state of 3rd-item
[*keyname3*] => 89.92
[*keyname4*] => unit of 3rd-item
)
Array (
[*keyname0*] => group-id
[*keyname1*] => name of 4th-item
[*keyname2*] => state of 4th-item
[*keyname3*] => 89.70
[*keyname4*] => unit of 4th-item
)
...
My aim is to calculate over the multiple items/arrays that get (dynamically) created by the foreach-loop
The calculation should follow this logic: deduct the value of keyname3 of the 2nd item/array (i. e. 93.12) from the value of keyname3 (i. e. 93.42) of the 1st item/array and so forth (i. e. 2nd from 1st, 3rd from 2nd, 4th from 3rd, 5th from 4th and so forth)
The results for the first arrays displayed above should be accordingly:
93.42 - 93.12 = -0.30
93.12 - 89.92 = -3.20
89.92 - 89.70 = -0.22
...
My attempts
Creating a “shift” in the variable $data with next() or arrray_slice(): $data['keyname3']-array_slice($data['keyname3'], 3, 1). This didnt work.
After that, my theory was to use two variables that derive from different SQL-requests. I used OFFSET in one of my SQL-requests in order to skip the first array. I then created a nested foreach-loop. This returned some valid results (among them my wanted values), but due to the nested foreach, for every iteration of the superordinated foreach it iterated through all values of the subordinate foreach (if that makes sense). By using a break, I was able to at least get the first value right. This was the nearest I could get to what I actually want. This is what the code looked like at this point (divs are wrapped in a foreach like so "foreach($result as $data) :" and ending with "endforeach;"):
<div class="classa">
<div><img class="classb" src="../../../img/test.png" alt="Image"></div>
<div class="classc"><p><?php echo number_format((round($data['keyname3'],2)),2,'.',' ') . " " . $data['keyname6']; ?></p></div>
<div class="classd"><p><?php echo $data['keyname2'] ?></p></div>
</div>
<div class="classe">
<p>
<?php
foreach($resultdiff as $key => $value) {
echo (round($value['keyname3']-$data['keyname3'],2));
if (++$count == 1) break;
}
?>
</p>
</div>
My output
This code in combination with the SQL-request displays eight elements with a picture, the name, the value of the according item and the calculated value in the browser. The 1st element contains the correct calculation for that item and shows the value of -3.50. So far so good. The following items then display a list of values, like the following.
2nd: 0, -3.2, -3.42, -4.99, -5.21, -5.22, -5.43, -5.55
3rd: 3.2, 0, -0.22, -1.79, -2.01, -2.02, -2.23, -2.35
...
The bold values are the correct values for that specific element. When I hit the load-button it really gets queer, because all values are stacked upon the previous. So the nested foreach loop with the separate SQL-request doesnt seem to really work for me! Is there a way to avoid a separate SQL-request with another variable and just use the already existing variable $data for this task?
I am an absolute beginner and not at all sure, whether this is alltogether a totally wrong approach or a possible right track. I would really appreciate if someone could break this issue down for me or nudge me in the right direction. Every help is more than welcome, since this is a must-have for my project.
BTW: I haven't yet looked into alternative options, like using JavaScript. If that might be the more suitable approach to get the wanted result, this would also be fine with me. I am still clinging on to PHP for this issue.
As CBroe stated in the comments, you can just use the key/index in the foreach loop to create the sum
<?php
$data = [
[
'indexname0' => 'group-id',
'indexname1' => 'name of 1st-item',
'indexname2' => 'state of 1st-item',
'indexname3' => 93.42,
'indexname4' => 'unit of 1st-item',
],
[
'indexname0' => 'group-id',
'indexname1' => 'name of 1st-item',
'indexname2' => 'state of 1st-item',
'indexname3' => 93.12,
'indexname4' => 'unit of 1st-item',
],
[
'indexname0' => 'group-id',
'indexname1' => 'name of 1st-item',
'indexname2' => 'state of 1st-item',
'indexname3' => 89.92,
'indexname4' => 'unit of 1st-item',
],
[
'indexname0' => 'group-id',
'indexname1' => 'name of 1st-item',
'indexname2' => 'state of 1st-item',
'indexname3' => 89.70,
'indexname4' => 'unit of 1st-item',
],
];
foreach($data as $index => $value) {
if (!isset($data[$index+1])) continue;
echo $data[$index+1]['indexname3'] - $data[$index]['indexname3'].'<br />';
}
demo

How to detect and avoid infinite loop in PHP

This question is not about a bug in my PHP code (for the moment I don't have any PHP script, I am still thinking about the algorithm). Here is the problem:
I'm currently working on a mechanical piece manager which would be able to build a mechanical piece based on internal part (for example, I got a piece which is a Bike, and for that piece, I need 2 wheels, 1 handlebar, and for a wheel I need a tire etc).
Each internal part is also a mechanical piece in my database and is linked with a unique ID (and has a folder which contains many PDF, many 3D files, etc).
I got a GUI (in HTML) representing my database and each piece has a "Build" button to gather all files required to build internal piece.
For example:
My bike has the ID n°1, a wheel has the ID n°2 and the handlebar has the ID n°3.
The algorithm is pretty simple but vulnerable with infinite loop.
How could I do to avoid this following case: What if my bike (id 1) need a wheel (id 2), and my wheel need a bike...which needs a wheel which need a bike......?
Thank you very much,
During the execution of your build function, you would just keep track of all components that you have already produced a result for -- in a hash --, and if you encounter one of those again, you just ignore it.
Here is some boilerplate code you could use for inspiration:
// Sample "database":
$components = array(
1 => array (
"id" => 1,
"name" => "bike",
"needs" => array (
array ("id" => 2, "count" => 2), // 2 wheels
array ("id" => 3, "count" => 1), // 1 handlebar
),
"folder" => "/my/folders/bike"
),
2 => array(
"id" => 2,
"name" => "weel",
"needs" => array(
array("id" => 4, "count" => 1), // 1 tire
array("id" => 1, "count" => 1) // 1 wheel?? - erroneous information!
),
"folder" => "/my/folders/wheel"
),
3 => array(
"id" => 3,
"name" => "handlebar",
"needs" => array (),
"folder" => "/my/folders/handlebar"
),
4 => array(
"id" => 4,
"name" => "tire",
"needs" => array(),
"folder" => "/my/folders/tire"
)
);
// Build function: returns a list of folders related
// to all the parts of the given component.
function build($componentId, $components, $hash = array()) {
// Protection against infinite recursion:
if (isset($hash[$componentId])) return [];
$elem = $components[$componentId];
// set hash, keyed by component ID.
$hash[$componentId] = 1;
// Add folder for this component
$folders[] = $elem['folder'];
// Collect folders of dependent components recursively
foreach($elem['needs'] as $child ) {
// ... pass the hash as third argument
$folders = array_merge($folders, build($child["id"], $components, $hash));
}
return $folders;
}
// Example call: build component with ID 1, returning a list of folders:
print_r (build(1, $components));
The output of the above code would be:
Array
(
[0] => /my/folders/bike
[1] => /my/folders/wheel
[2] => /my/folders/tire
[3] => /my/folders/handlebar
)
So when the bike was encountered a second time, it was just ignored.
You should differentiate the child-parent relations.
A bike can contain a wheel as a child item and a wheel may have a bike as its parent item. Also one screw and tire can be child items of the wheel.
Navigation should have one direction, either from parent items to child items or the opposite.

PHP Count Number of Times A String Appears As A Value Inside An Array

So I looked around here for a bit but cant seem to get this right, so I am forced to make a new post. I gave it an effort! Don't hurt me.
Sample Array:
$ndata = Array
(
[ARMOR_HEAD] => Andariel's Visage
[ARMOR_TORSO] => Blackthorne's Surcoat
[ARMOR_FEET] => Illusory Boots
[ARMOR_HANDS] => Gauntlets of Akkhan
[ARMOR_SHOULDERS] => Pauldrons of Akkhan
[ARMOR_LEGS] => Blackthorne's Jousting Mail
[ARMOR_BRACERS] => Nemesis Bracers
[ARMOR_MAINHAND] => Gyrfalcon's Foote
[ARMOR_OFFHAND] => Jekangbord
[ARMOR_WAIST] => Blackthorne's Notched Belt
[ARMOR_RRING] => Ring of Royal Grandeur
[ARMOR_LRING] => Stone of Jordan
[ARMOR_NECK] => Kymbo's Gold
)
$count = count(preg_grep('Akkhan', $ndata));
print_r($count);
So this is only returns 1 instead of 2. I also tried array_search(), but that simply returns a the first found with its key. Or in_array but that is just boolean I guess.. Is there a better way to go about this?
The first parameter to preg_grep is not a string, it is a regular expression pattern represented as a string. Try this:
preg_grep('/Akkhan/i', $ndata)
For more information, see the documentation page for preg_grep.

associating two separate arrays for itinerary system

I am trying to build a travel itinerary system. The user selects the dates of travel, and then may add items to each day.
I have an array of dates, stored in a session in the format:
array(
(int) 0 => '2012-08-25',
(int) 1 => '2012-08-26',
(int) 2 => '2012-08-27'
)
They will then choose attractions, which I wish to store in an array in the format:
array(
(int) 0 => array(
'Attraction' => array(
'attraction_id' =>'1',
'name' => 'Place One',
)
),
(int) 1 => array(
'Attraction' => array(
'attraction_id' => '2',
'name' => 'Place Two',
)
),
I'd like to be able to output:
2012-08-25
Place One
Place Two
2012-08-26
nothing here yet!
2012-08-27
nothing here yet!
So, each item of the first array contains an array of items, if that makes sense. I am struggling with the logic of associating the keys of the days array with the items array.
I looked at array_merge but that doesn't seem to do what I need.
Is there an easy way to achieve this?
This code does exactly what you ask. Unfortunately, I fear your question doesn't reflect your aim given the example. Using keys to link data will led to 1-1 relationship, where as you seem to need a 1-n. You should have a foreign key field in the attraction array, like date_id.
$array= array();
foreach($dates as $date_key=>$date){
$array[$date]=array();
foreach($attractions as $attraction_key=>$attraction){
if($date_key==$attraction_key){
$array[$date][]=$attraction['Attraction']['name'];
}
}
}

Append string to an exitsting array key? PHP

I want to append the key from $teasers to the key of the array contained within each $teasers element and then create an associative array that contains the appended keys for its key and the content of the sub array for its content. Following? I hope so, if not here's an example of my desired end product:
This is a simplified version of the multidimensional array I'm working with:
$teasers[0]=array('id' => 4,
'title' => 'How to determine the speed of an african swallow',
'content'=> 'Its really quite simple...')
$teasers[1]=array('id' => 5,
'title' => 'Man alleged to be cereal killer after breakfast',
'content' => 'Turns out eating a delicious bowl of froste...')
I'm working towards turning it into this:
$data Array(
'/*Key from subarray+$teasers key*/' => '/*content from subarray*/',
'id0' => '4',
'title0' => 'How to determine the speed of an african swallow',
'content0' => 'Its really quite simple...',
'id1' => '5',
'title1' => 'Man alleged to be cereal killer after breakfast',
'content1' => 'Turns out eating a delicious bowl of frosted...')
Still not following? I don't blame you. Maybe this will help. I was originally going about it like this until I realized you can't pass a variable into a foreach loop. ):
foreach ($teasers as $key => $blogentry) {
foreach($blogentry as $entrykey => $content){
//Basically I would like to append $key to the end of $entrykey
//so that I can essentially access all of the data from one array($data[])
$data[$entrykey.$key] = $content;
}
}
I'm more than happy to do anything I can to make things more clear or help you help me. Thanks for your time in advance!!
I think your code should work. Add $data = array(); before your loops.

Categories