Sorting PHP Randomised numbers by size - php

So I've got this:
$h = $user_goals;
while($h > 0) {
randomScorer();
$minute = rand(0,90);
echo "(".$minute.")<br>";
$h--;
Basically, what it does is, $user_goals, has a load of factors drawn into it and creates a number, between 0-5, and this information is used to generate the times of the goals, using the above PHP function.
It's working, it's brilliant, etc. However, the numbers are appearing in random order in which they are generated and so I was wondering:
Is there any way to sort these numbers?
Would I put them into an array during this iteration methodology, and then sort the array by the number's value?
Any help is greatly appreciated!

That is why PHP provides us Sort functions. Have a look here.
<?php
$fruits = array("lemon", "orange", "banana", "apple");
sort($fruits);
?>
Since your array is NUMERIC, you need to use the FLAG along with the sort function.
sort($goals, SORT_NUMERIC);
print_r($goals);

Same idea, using sort() but also uses range and array_walkto set up your array a little closer to how you already do it:
$goal_array = range(1, $user_goals); // Warning, assumes $user_goals is number
array_walk($goal_array, function(&$goal) {
randomScorer();
$goal = rand(0,90);
});
sort($goal_array, SORT_NUMERIC);

Related

Resorting integers in PHP to remove gaps

I'm searching for an algorithm to remove gaps between numbers. Example of my problem:
Here is a range of integers: [1,2,3,4,9,10,11,17...]
I need to make those numbers like this: [1,2,3,4,5,6,7,8...]
Can anyone provide me with a working example of PHP code to obtain such a result?
You should fetch min and max from an array and create the range,
$min = min($arr);
$max = max($arr);
print_r(range($min,$max));
You can make by using range function as:
// given array 2,4,6 and 9 are missing.
$arr1 = array(1,3,5,7,8,10);
// construct a new array using range function by giving min(given array) and max(given array) value
$arr2 = range(min($arr1),max($arr1));

Why does max(array_push()) not find max?

Up front, I would like to clarify that I am not looking for a workaround to find max--I already have the solution for accomplishing that goal. What I am curious about is why max(array_push()) doesn't work.
I have an array with many values in it, and want to find the max of specific values within that array. Existing array:
$array1 = array(2,6,1,'blue','desk chair');
The basic idea is to create a new array consisting of those specified values, and then find the max of that new array. I attempted to make this effort operate all on one line:
$max = max(array_push($array2, $array1[0], $array1[1], $array1[2]));
//this doesn't work at all, since $array2 doesn't already exist, as per the PHP manual
I changed to code to first create $array2, but didn't assign values at that time, just to see if the code works.
$array2 = array();
$max = max(array_push($array2, $array1[0], $array1[1], $array1[2]));
//$array2 is populated, but $max is not assigned
The obvious solution is to assign values to $array2 at creation and then use max() by itself. I'm just curious as to why max(array_push()) doesn't find max, since compounded functions normally operate from inside to outside.
Thank you.
max needs an array to work with but array_push returns an integer and actually uses the provided array by reference, you have to do :
$array2 = array();
array_push($array2, $array1[0], $array1[1], $array1[2])
$max = max($array2);
Alternatively do:
$array2 = array($array1[0], $array1[1], $array1[2]);
$max = max($array2);
A 3rd option (though not the cleanest one):
$array2 = array();
$max = max($array2 = array_merge($array2, [$array1[0], $array1[1], $array1[2]]));
For reference, see:
http://php.net/manual/en/function.max.php
http://php.net/manual/en/function.array-push.php
You could also use array_slice():
$max = max(array_slice(
$array1,
0,
3
));
if
the values you are interested in are in a sequence
you know offset and length of the sequence
For reference, see:
http://php.net/manual/de/function.array-slice.php
http://php.net/manual/de/function.max.php
For an example, see:
https://3v4l.org/nMK1Z

I want to make custom array shuffle in php with respect to integer

Looking the function below:
function CustomShuffle($arr, $para){
............................
............................
return $array;
}
Suppose this is an array:
$array = array("red","green","blue","yellow","purple");
looking output something like below (May be different ordered but must be same for same integer parameter)
$result = CustomShuffle($array, 10);
// output: array("blue","purple","yellow","red","green") same
$result = CustomShuffle($array, 12);
// output: array("purple","yellow","red","green","blue")
$result = CustomShuffle($array, 10);
// output: array("blue","purple","yellow","red","green") same
$result = CustomShuffle($array, 7);
// output: array("blue","yellow","purple","red","green")
Simply, array will be shuffled with respect to integer parameter but output will be same for same parameter. Is it possible?
Yes this is possible, how it happens does come down to a desired implementation and how many permutations you wish to allow. A very naive method of accomplishing this is to have a loop that runs $para times within CustomShuffle that would array_shift() an element then array_push() that same element. This method would only give you count($array) possible outcomes, meaning numbers congruent modulo count($array) would produce the same result.
The optimal algorithm would allow you to take advantage of the maximum combinations, which would be gmp_fact(count($array)), or simply the factorial of the length of the input array. There is no possible way to achieve more unique combinations than this value, so no matter what algorithm you design, you will always have a constraint on the value of $para until you eventually encounter a combination already seen.

How to change order of substrings inside a larger string?

This is fairly confusing, but I'll try to explain as best I can...
I've got a MYSQL table full of strings like this:
{3}12{2}3{5}52
{3}7{2}44
{3}15{2}2{4}132{5}52{6}22
{3}15{2}3{4}168{5}52
Each string is a combination of product options and option values. The numbers inside the { } are the option, for example {3} = Color. The number immediately following each { } number is that option's value, for example 12 = Blue. I've already got the PHP code that knows how to parse these strings and deliver the information correctly, with one exception: For reasons that are probably too convoluted to get into here, the order of the options needs to be 3,4,2,5,6. (To try to modify the rest of the system to accept the current order would be too monumental a task.) It's fine if a particular combination doesn't have all five options, for instance "{3}7{2}44" delivers the expected result. The problem is just with combinations that include option 2 AND option 4-- their order needs to be switched so that any combination that includes both options 2 and 4, the {4} and its corresponding value comes before the {2} and it's corresponding value.
I've tried bringing the column into Excel and using Text to Columns, splitting them up by the "{" and "}" characters and re-ordering the columns, but since not every string yields the same number of columns, the order gets messed up in other ways (like option 5 coming before option 2).
I've also experimented with using PHP to explode each string into an array (which I thought I could then re-sort) using "}" as the delimiter, but I had no luck with that either because then the numbers blend together in other ways that make them unusable.
TL;DR: I have a bunch of strings like the ones quoted above. In every string that contains both a "{2}" and a "{4}", the placement of both of those values needs to be switched, so that the {4} and the number that follows it comes before the {2} and the number that follows it. In other words:
{3}15{2}3{4}168{5}52
needs to become
{3}15{4}168{2}3{5}52
The closest I've been able to come to a solution, in pseudocode, would be something like:
for each string,
if "{4}" is present in this string AND "{2}" is present in this string,
take the "{4}" and every digit that follows it UNTIL you hit another "{" and store that substring as a variable, then remove it from the string.
then, insert that substring back into the string, at a position starting immediately before the "{2}".
I hope that makes some kind of sense...
Is there any way with PHP, Excel, Notepad++, regular expressions, etc., that I can do this? Any help would be insanely appreciated.
EDITED TO ADD: After several people posted solutions, which I tried, I realized that it would be crucial to mention that my host is running PHP 5.2.17, which doesn't seem to allow for usort with custom sorting. If I could upvote everyone's solution (all of which I tried in PHP Sandbox and all of which worked), I would, but my rep is too low.
How would something like this work for you. The first 9 lines just transform your string into an array with each element being an array of the option number and value. The Order establishes an order for the items to appear in and the last does a usort utilizing the order array for positions.
$str = "{3}15{2}2{4}132{5}52{6}22";
$matches = array();
preg_match_all('/\{([0-9]+)\}([0-9]+)/', $str, $matches);
array_shift($matches);
$options = array();
for($x = 0; $x < count($matches[0]); $x++){
$options[] = array($matches[0][$x], $matches[1][$x]);
}
$order = [3,4,2,5,6];
usort($options, function($a, $b) use ($order) {
return array_search($a[0], $order) - array_search($b[0], $order);
});
To get you data back into the required format you would just
$str = "";
foreach($options as $opt){
$str.="{".$opt[0]."}".$opt[1];
}
On of the bonuses here is that when you add a new options type inserting adjusting the order is just a matter of inserting the option number in the correct position of the $order array.
First of all, those options should probably be in a separate table. You're breaking all kinds of normalization rules stuffing those things into a string like that.
But if you really want to parse that out in php, split the string into a key=>value array with something like this:
$options = [];
$pairs = explode('{', $option_string);
foreach($pairs as $pair) {
list($key,$value) = explode('}', $pair);
$options[$key] = $value;
}
I think this will give you:
$options[3]=15;
$options[2]=3;
$options[4]=168;
$options[5]=52;
Another option would be to use some sort of existing serialization (either serialize() or json_encode() in php) instead of rolling your own:
$options_string = json_encode($options);
// store $options_string in db
then
// get $options_string from db
$options = json_decode($options_string);
Here's a neat solution:
$order = array(3, 4, 2, 5, 6);
$string = '{3}15{2}3{4}168{5}52';
$split = preg_split('#\b(?={)#', $string);
usort($split, function($a, $b) use ($order) {
$a = array_search(preg_replace('#^{(\d+)}\d+$#', '$1', $a), $order);
$b = array_search(preg_replace('#^{(\d+)}\d+$#', '$1', $b), $order);
return $a - $b;
});
$split = implode('', $split);
var_dump($split);

php - array_fill negative indices

When using php array_fill and negative indices, why does php only fill the first negative indice and then jump to 0.
For example:
array_fill(-4,4,10) should fill -4, -3, -2, -1 and 0 but it does -4, 0, 1, 2, 3
The manual does state this behaviour but not why.
Can anyone say why this is?
Looking at the source for PHP, I can see exactly why they did this!
What they do is create the first entry in the array. In PHP, it looks like:
$a = array(-4 => 10);
Then, they add each new entry like this:
$count--;
while ($count--) {
$a[] = 10;
}
If you do this exact same thing yourself, you'll see the exact same behavior. A super short PHP script demonstrates this:
<?php
$a = array(-4 => "Apple");
$a[] = "Banana";
print_r($a);
?>
The result: Array ( [-4] => Apple [0] => Banana )
NOTE
Yes, I did put in PHP instead of the C source they used, since a PHP programmer can understand that a lot better than the raw source. It's approximately the same effect, however, since they ARE using the PHP functions to generate the results...
Maybe because it's stated in the doc: http://www.php.net/manual/en/function.array-fill.php
If start_index is negative, the first index of the returned array will be start_index and the following indices will start from zero (see example).

Categories