Question:
How can I iterate below so it checks existence of key "round_1", next script run it should check existense of key "round_2", etc. Everytime it would encounter that the key is missing it should create the key.
It is working with "round_1" as expected.
<?php
// Create array skeleton.
$array_skeleton = array_fill(1, 3, "");
print_r($array_skeleton);
// Populate the skeleton with random numbers, values [1 to 6].
foreach($array_skeleton as $key => $value) {
$populated_array[$key] = random_int(1, 6);
};
print_r($populated_array);
// Create empty array for purpose to become multidimensional array.
$scorecard = [];
// Check if [round_1] is missing, if so create [round_1] and populate it.
if(!array_key_exists("round_1", $scorecard)) {
echo "round_1 is missing, creating it";
$scorecard["round_1"] = $populated_array;
}
print_r($scorecard);
Outcome works fine as expected, after first script run:
(
[round_1] => Array
(
[1] => 3
[2] => 4
[3] => 1
)
)
Expected outcome, after second script run:
Note! It is correct that the values would be different per each round since they are randomly created.
(
[round_1] => Array
(
[1] => 3
[2] => 4
[3] => 1
)
[round_2] => Array
(
[1] => 1
[2] => 4
[3] => 2
)
)
I think your entire code can be simplify:
first define function for create array with random number:
function createRandomNumberArray($numOfElem, $maxRange) {
for ($i = 0; $i < $numOfElem; $i++)
$res[] = random_int(1, $maxRange);
return $res;
}
Second, assuming your keys are made of "round_#INT#" pattern you can do
$biggest = max(array_map(function ($e) {$p = explode("_", $e); return $p[1];}, array_keys($arr)));
And now do:
$newKey = "round_" . ($biggest + 1);
$scorecard[$newKey] = createRandomNumberArray(3,6);
Reference: array-map, explode, max, random-int
I would like to split an array into three array that have similar sums - as close as possible
I have array
$arr = [1,2,4,7,1,6,2,8];
Desire output for example:
a = 8,2 // as sum is 10
b = 7,2,1 // as sum is 10
c = 6,4,1 // as sum is 10
Thanks
You can use the following algorithm:
Sort the input array from big to small
Create output array
for each element in the input - insert to the lowest sum in the output array.
Consider the following code:
$arr = [1,2,4,7,1,6,2,8];
sort($arr);
$arr = array_reverse($arr); // big to small
$out = array(array(),array(),array()); // output array
for($i = 0; $i < 8; $i++) {
$sums = array_map("array_sum" ,$out); // get all current sums of the array
$index = array_keys($sums, min($sums))[0]; // get the min sum
$out[$index][] = $arr[$i]; // add the element to the array with the lowest sum
}
echo print_r($out, true);
Now you will get:
array:
[0]: array:
[0] => 8
[1] => 2
[2] => 1
[1]: array:
[0] => 7
[1] => 2
[2] => 1
[2]: array:
[0] => 6
[1] => 4
Hi I have array like this
Array (
[0] => stdClass Object (
[id] => 1930 [value] => 20)
[1] => stdClass Object (
[id] => 1931 [value] => 30 )
[2] => stdClass Object (
[id] => 1937 [value] => 30 )
[3] => stdClass Object (
[id] => 1938 [value] => 20 )
)
I want to fetch random array from this. The Id which has greater value(%) should be fetched more time (That value is %).
Make a another array and repeat the index of array for the number of times its value is and then fetch the values randomly this would do what you want
The above mentioned array would be
array(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,)
$arr = Array (
(Object) array (id => 1930, value => 20),
(Object) array (id => 1931, value => 30),
(Object) array (id => 1937, value => 30),
(Object) array (id => 1938, value => 20));
// count sum of all values
$sum = array_reduce($arr, function ($c, $i) { return $c += $i->value; }, 0);
// get random
$rand = mt_rand(0, $sum);
echo $rand . " ";
// select 1st item that sum of values >= random value
$new = array_filter($arr, function ($i) use (&$rand) { if($rand > 0 && ($rand -= $i->value) <= 0) return true; else return false; });
// change key to 0
$new = array_values($new);
echo $new[0]->id;
One way to solve this is to make a list of the cummulative sum of the values in the array, for instance if the values are 3, 1, and 2 the cummulative sums would be 3, 4 and 6. Then when you want to get a random element, you generate a random integer between 1 maximum sum, and then pick the element whose cumulative sum is largest of those whos cumulative sum is smaller than or equal to the random number. In that way, the chanse of any element being picked is proportional to its value.
So here is the setup, creating the cumulative sums:
var $cumsum = array();
var $sum = 0;
foreach($array as $obj) {
$sum += $obj->value;
array_push($cumsum, $sum);
}
var $maxsum = end($cumsum);
And here is the function actually picking an element:
function getRandomObject() {
var $r = random(1, $max);
if($r < $cumsum[0]) return $array[0];
for($i = 0; $i < count($cumsum); $i++)
if($cumsum[$i]) > $r)
return $array[$i--];
return $array[$i];
}
Disclaimar: I have not tested this code, so don't expect it to run on a copy paste. Also, whatever code you use you should probably make sure it returns elements with the right probability using a monte carlo method.
I have an array which has multiple sets of data.
Is it possible to sum elements (not all) of the array. For example, is it possible to sum the first 5 sets of data in an array, then then next 7, then the next three etc.
EDIT:
I've tried the following but with not joy:
for ($p=0; $p<=8; $p++){
$tot = 0;
$resp = 0;
$tot = $tot + $row4['Total_Staff'];
$resp = $resp + $row4['Total_Resp'];
}
Clearly I am not using this correctly!
Array Output (print_r output):
Array ( [department] => Central>ACME>BusDev [Total_Staff] => 4 [Total_Resp] => 0 )
Array ( [department] => Central>ACME>ChemDev [Total_Staff] => 7 [Total_Resp] => 0 )
Array ( [department] => Central>ACME>Admin [Total_Staff] => 1 [Total_Resp] => 0 )
Array ( [department] => Central>ACME>Chemistry [Total_Staff] => 4 [Total_Resp] => 0 )
Use array_splice() to remove $numOfElems elements from the array and the return them. Use array_sum() to calculate the sum. Repeat the process until the array is empty.
$array = array(/* your array */)
$sets = array(5,7,3);
$sum_arr = array();
foreach ($sets as $numOfElems) {
while (!empty($array)) {
$elem_arr = array_splice($array, 0, $numOfElems);
$sum[] = array_sum($elem_arr);
}
}
print_r($sum_arr);
This will repeat the process with the same sets until it reaches the end of array. If you only want count($sets) number of iterations, then perhaps, you could change while to if.
Demo
Is it possible to divide a number into an array based on its value?
For example:
$val = 3;
// do something here to convert the number 3 into 1's
Array
(
[0] => 1
[1] => 1
[2] => 1
)
$array = array_fill(0, $val, 1);
array_fill(0, $val, 1);
will create an array
Array
(
[0] => 1
[1] => 1
[2] => 1
)
Do something like this:
$arr = Array();
for ($i=0;$i<$val;$i++) {
$arr[] = 1;
}
But with larger numbers you may need something different.
Another slightly shorter solution is to use range()
$val = 3;
$array = range(1, $val);
print_r($array);
// Output:
// Array
// (
// [0] => 1
// [1] => 2
// [2] => 3
// )
It's not possible for the value to be negative, or zero.
That's good, because all of these solutions (including loops) won't work with a zero or negative. However, range() will give you a different result (the 5 digit range of 1 to -3, for example).