I have just coded a basket/cart system for my websitye but I am sturggling on getting the total cost for items in the basket? I have the price for each item (i loop basket items in a loop) what the main question here is how can I add money strings together and get a valid money string total amount like below...
£4.56 +
£2.35 +
£3.00
= £9.91
£2.83 +
£19.83 +
£22
= £44.66 (I think)
you need to remove tha '£' from each item and then convert it to a integer then you create a variable named sum and in a loop you add each element to the sum , there you are the algorithm :
int sum = 0;
for_each (item i in basket)
{
string tmp = i.get_price() ; // get_price returns "£x" string
sum += to_integer(tmp.sub_str(1,tmp.length()-1));
/* copy from the pos 1 to the end ignoring the '£'*/
}
then the sum variable contains what you want :D
Use a number formatter:
$f = new NumberFormatter("en-GB",NumberFormatter::CURRENCY); //Make sure you use the correct locale
$total = 0;
foreach ($arrayOfCurrencies as $number) {
$c = $p = null;
$total += $f->parseCurrency($number, $c, $p);
}
return $f->formatCurrency($total,$c);
Don't use things like substring for this when there's built-in ways to do it.
Related
I have:
$current_price = 100;
$array_price = array(10,20,30,40,50,60,70,80,90, 140,150)
I want to compare the current price with the prices in the array, find the smallest abs difference and save the price from the array that has the smallest difference with the current price
$diff = '';
$diff_array=array();
foreach ($array_price as $value) {
$diff = abs($current_pric - $value);
$diff_array[] = $diff;
}
echo(min($diff_array) . "<br>");
In this case i can find the smallest difference but how i can save the price from the array that is connected with that smallest difference?
You don't need $diff_array. Just loop through the array testing whether the current difference is smaller than the smallest difference seen so far. If so, save the current difference and the current price in variables.
$smallest_element = $array_price[0];
$smallest_diff = abs($smallest_element - $current_price);
for ($i = 1; $i < count($array_price); $i++) {
if (abs($array_price[$i] - $current_price) < $smallest_diff) {
$smallest_diff = abs($array_price[$i] - $current_price);
$smallest_element = $array_price[$i];
}
}
echo "Closest price is $smallest_element\n";
I would approach the problem a little bit different.
Just save the value of the variable if it is lower than the saved one, and also keep the index of the array so you will have the index and the value of the array.
You can approach this by using array_walk with abs and than in difference array use min & array_search retrieve the min array element which is the lower difference
$b = [];
array_walk($array_price, function(&$v,&$k) use ($current_price, &$b){
$b[$v] = abs($current_price - $v);
});
echo 'Minimam array element is : '.array_search(min($b), $b).', which has difference : '.min($b);
Live working example : https://3v4l.org/QasYM
I would like to "for loop" through a large number and build an array of items that is x% one way and x% another.
For the sake of exmaple:
I want to generate an array of fake customer records.
The idea is that at the end of the loop, I will have an array that contains 20% users that only contain a customer id and 80% users that contain first name, last name and known details. The generation of the details isn’t important, it’s the percentage that is split in the loop that is.
So far this is what I was working with:
$percentage = $percent_known / 100;
$percnum = $this->number_of_records * $percentage;
$iterat = $this->number_of_records / $percnum;
for ($i=0; $i < $this->number_of_records; $i++) {
if ($i % $iterat == 0) {
//add known records
}
else {
//just add a customer id
}
}
when put 80 as the value of $percent_known I get an iterat of 1.25 and all my records are known.
You can simplify it to fill in all of the known ones ( by filling in up to $percnum) and then add the unknown ones. If you want them to be random, then just use shuffle() at the end to mix the results together...
$percentage = $percent_known / 100;
$percnum = $this->number_of_records * $percentage;
$customers = [];
for ($i=0; $i < $this->number_of_records; $i++) {
if ($i < $percnum) {
//add known records
}
else {
//just add a customer id
}
}
shuffle($customers);
If the values are the same - you can always generate a batch using array_fill() rather than using a loop and merge the two formats and again shuffle the results.
I'm trying to distribute 100% to total numbers (not equally), it can be done manually but I'm looking for a automatically way in PHP. I had to open calculator and get it done for manual.
What I'm trying to achieve is the result similar to this:
$value = 10000;
$total_numbers = 9
$a1 = $value*0.2;
$a2 = $value*0.175;
$a3 = $value*0.15;
$a4 = $value*0.125;
$a5 = $value*0.1;
$a6 = $value*0.08;
$a7 = $value*0.07;
$a8 = $value*0.05;
$a9 = $value*0.04;
So as you can see, the first variables have more quantity than the later ones, but if you add these, it will be 1 which is 100%. So lets say I have total_numbers=20 then I'll have to re-write it and get a calculator and do it the hard way to accomplish my goal. Is there any way this can be done automatically with a function where I can just tell the total number and it can distribute it to proportions or something?
The first one will always be bigger than rest, then second one bigger than rest but smaller than first, third one being greater than rest but small than first and second, and so on.
function distributeValue($value, $num) {
$parts = $num * ($num + 1) / 2;
$values = [];
for ($i = $num; $i > 1; --$i) {
$values[] = round($value * $i / $parts);
}
$values[] = $value - array_sum($values);
return $values;
}
var_dump(distributeValue(10000, 9));
This works by calculating the $numth triangle number (the number you get by adding all the numbers from 1 to $num) and dividing the total value up into this number of parts.
It then starts by taking $num parts, then $num-1 parts and so on.
Since it's rounding the numbers, the last step is to take the total minus all the other values which is around one part. If you are fine with getting floats instead of ints out, then you can remove the $values[] = $value - array_sum($values); line and change the condition of the for loop to $i > 0.
I have an array of value series like:
$series = [100,300,500,800,1000,3000,5000,10000,15000,20000];
Another value getting from DB like:
$point = $data[‘earned_point’];
I need the highest match from the series. such as I got a value from db (1500) the highest match of the value is 1000 in the series, so I need to get the $series[4] and make it
$reward = $series[4] * 0.1;
I'll run it in a loop to do it for all the values got from DB.
I'm posting alternate code as the accepted answer while is correct can be very inefficient if you are working with a large array.
<?php
function computeReward($series, $point, $percent = 0.1){
arsort($series); // sort the series in reverse so we can pass any array and the highest number will be the first because we are looking for a number lower or equal to our point
foreach($series as $min_point){
if($min_point <= $point){
return $min_point * $percent; // return the min_point * the percentage, this stops the loop there for being more efficient
}
}
}
$series = [100,300,500,800,1000,3000,5000,10000,15000,20000];
$point = $data['earned_point'];
$reward = computeReward($series, $point);
?>
Do you mean you want to get which highest $series item is equal or less than $point ?
<?php
$series = [100,300,500,800,1000,3000,5000,10000,15000,20000];
$point = $data['earned_point'];
foreach ($series as $min_point) {
if ($point >= $min_point) {
$matched_min_point = $min_point;
}
}
$reward = $matched_min_point*0.1;
Let me know if this works for you
I'm trying to assign a different random number on each item in a foreach loop but I'd like the number to stay the same for one day.
I've tried simply adding <?php echo rand(0,20); ?> but this obviously just creates a random number per each refresh.
Is there anyway I could keep the same random number per each item for one day without adding it to the database.
for example:
item 1 = 2
item 2 = 18
item 3 = 13
item 4 = 6
Stays the same for 1 day then changes
You can do this by programming your own random number generator. This guide shows you how to do it.
Note: Code below from sitepoint
class Random {
// random seed
private static $RSeed = 0;
// set seed
public static function seed($s = 0) {
self::$RSeed = abs(intval($s)) % 9999999 + 1;
self::num();
}
// generate random number
public static function num($min = 0, $max = 9999999) {
if (self::$RSeed == 0) self::seed(mt_rand());
self::$RSeed = (self::$RSeed * 125) % 2796203;
return self::$RSeed % ($max - $min + 1) + $min;
}
}
To call it
// set seed
Random::seed(42);
// echo 10 numbers between 1 and 100
for ($i = 0; $i < 10; $i++) {
echo Random::num(1, 100) . '<br />';
}
Now set your seed based on the current date with the php date function
// set seed based on date with
Random::seed(date("z") + 1);
This will give you the same numbers every year. If you don't want this, use the seed variable of rubo77. With this version you can ensure to get the same number on different machines (can't guarantee that with srand).
Maybe you could try something like:
$not_random_at_all = base_convert(md5($item . date('l jS \of F Y')), 16, 10);
Where $item is the number of your item (or anything that identifies the item).
It just converts the MD5-Hash of the current date concatenated with your item number to integer.
That means a different random number for every item daily.
Remember that MD5 is not a random number generator and your results might bot be as random as they can be.
$seed = floor(time()/86400);
srand($seed);
foreach($list as $item){
echo $item.rand(0,20);
}
or to obtain the same value of rand in a determined time interval.
Another Example: you have an array of 20 elements and you need to obtain a random item every day but not to change in the 24h period (just imagine "Today's Photo" or similar).
$seed = floor(time()/86400);
srand($seed);
$item = $examplearray[rand(0,19)];
You obtain the same value every time you load the page all the 24h period.