I'am searching the best way to do that test in php :
So i have a list which contains numbers and I have to check the succesion of these numbers so if there is no succession it is necessary to announce an alert and to recover the missing index or the list of the missing indexes
So for example my array is like that:
Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 4 [4] => 6 [5] => 9 )
Here my algorithm must returns missing indexes are : [5,7,8]
If you make a range of the min and max value then use array_diff that should give you the result you want.
$arr = []; // your array
$range = range(min($arr), max($arr));
var_export(array_diff($range, $arr));
// [5,7,8]
https://3v4l.org/0pE3o
If you sort the numbers
sort($numbers);
You can use a nested loop.
foreach ($numbers as $k => $x) {
for ($n = $x + 1, $y = $numbers[$k + 1] ?? $x; $n < $y; $n++) {
$missing[] = $n;
}
}
The outer loop iterates the set of numbers, and the inner loop counts up from the current number to the next number.
Related
I am very newbie on programming, first studying PHP language about arrays. I can sort an array with sort function, but I got stuck here.
If i have input array(1,3,5,6,7,8,11,12,17,11)
I try to get output 12 or bigger number 2, but if I do print_r($array[i] - 1);
I just get 10-1=9. how can i get value 12?
and then if I have input array(1,2,3,5,6) I try to get output false because of the missing number 4.
I make sort function:
for(int j:0;j<=count($array) ;j++) {
for(int i:0;i<=count($array[i+1]);i++{
if($array[i]>$array[$+1]{
$temp=$array[$i+1];
$array[$i+1]=$array[$i];
$array[$i]=temp;
}
}
}
print_r($array) ;
Thanks if someone can help me or teach me? :)
You have a lot of syntax errors in your code. Check the comments under your question, they pretty much covered it.
To sort an array with a custom sort you can use this:
$array = array(1,3,5,6,7,8,11,12,17,11);
$arrayCount = count($array); // no need to evaluate the count on every iteration of the for loop
for($i=0; $i < $arrayCount - 1; $i++)
{
for($j = $i+1; $j < $arrayCount; $j++)
{
// if you want the array sorted from bigger to smaller number use `>` here
if($array[$j] < $array[$i])
{
$temp = $array[$i];
$array[$i] = $array[$j];
$array[$j] = $temp;
}
}
}
print_r($array);
which outputs:
Array
(
[0] => 1
[1] => 3
[2] => 5
[3] => 6
[4] => 7
[5] => 8
[6] => 11
[7] => 11
[8] => 12
[9] => 17
)
Now to retrieve a desired value from the array or false if it does not exist you would write something like this using the built in array_search() method:
// Check if array contains a value 12, if it does return the index location in the array
// returns false if the value is not found
$index = array_search(12, $array);
if($index === false)
{
echo 'Value does not exist in the array.';
}
else
{
echo 'Value '.$array[$index].' is at index '.$index.' in the array.';
}
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.
Let's say we have arrays like below.
$arr00 = [0,1,2,...,9]; // It includes 9 arrays. So the score should be 9.
$arr01 = [0,1,...,8]; // score = 8
...
$arr09 = [0]; // score = 0
ArrScore (definition): If an array include an array with all elements it
gets one point. So in this case $arr00's total score is 9. Because it
includes all other 9 arrays. And $arr09's score will be 0.
Actual Conditions
Our array elements could be random numbers. (not sequent orders ascending +1)
There could be thousands of arrays.
Our arrays are always flat. (no duplicated element in an array)
We are using php (any theoretical approach is also ok)
Think that you have a standard PC and you will order these arrays everyday once. (No need for the result of "which arr eats which ones". Just ArrScores.)
Goal is to order arrays by ArrScore. And we need ArrScores. What should be the approach? (Theoretical or practical)
If I understood right, this might help:
function compare($a,$b) {
if(count(array_intersect($a, $b)) == count($a)) return -1;
else return 1;
}
$arr0 = [0,2,4,7];
$arr1 = [7,0,2,9,4];
$arr2 = [4,2];
$arr = [$arr0,$arr1,$arr2];
usort($arr,"compare");
foreach($arr as $a) {
print_r($a);
}
prints:
Array ( [0] => 4 [1] => 2 ) Array ( [0] => 0 [1] => 2 [2] => 4 [3] => 7 ) Array ( [0] => 7 [1] => 0 [2] => 2 [3] => 9 [4] => 4 )
EDIT:
Compute the ArrayScore for each array:
$arr0 = [0,2,4,7];
$arr1 = [7,0,2,9,4];
$arr2 = [4,2];
$arr = [$arr0,$arr1,$arr2];
$arrayScores = [];
//initialize the Scores with 0
foreach($arr as $a){
$arrayScores[] = 0;
}
//run through all arrays
for($i=0;$i<count($arr);$i++){
//with $j=$i+1, every combination is only checked once
for($j=$i+1; $j<count($arr);$j++){
if(count(array_intersect($arr[$j], $arr[$i])) == count($arr[$j])) {
$arrayScores[$i]++;
}
if(count(array_intersect($arr[$i], $arr[$j])) == count($arr[$i])){
$arrayScores[$j]++;
}
}
}
This question is similar to a previous question of mine, but I formulated it wrong. I'm very sorry; here's the actual problem.
I have a file with thousands of numbers underneath each other. Let's simplify by using this:
4
7
1
9
3
3
8
6
2
6
5
1
What I need is to output a matrix (in the form of an array) with a variable number of matrix-rows. The numbers from the file have to be devided over the rows with the first number going to the first row, the second number to the second row, etc. Or, if you like, the 1st number, and every fourth number after that, go to column 1. The second number, and every fourth number after that, to column 2, etc. In the example below, the number of rows is 3:
array (
[0] => 4,9,8,6
[1] => 7,3,6,5
[2] => 1,3,2,1
)
And in this example, the number of rows is 4:
array (
[0] => 4,3,2
[1] => 7,3,6
[2] => 1,8,5
[3] => 9,6,1
)
The number of rows is variable.
Currently, with help of Oscar Jara, I now have this:
$path = "data.csv";
$array = explode("\n", file_get_contents($path));
$numbers = array();
foreach(array_chunk($array, 3) as $number){
$numbers[] = implode(",", $number);
}
But this outputs the numbers from the file over rows instead of columns:
array (
[0] => 4,7,1
[1] => 9,3,3
[2] => 8,6,2
[3] => 6,5,1
)
I get confused when transforming this code into dividing into columns. If you don't, then any help is appreciated.
Try this:
$path = "data.csv";
$data = file($path);
$numbers = Array();
$rowcount = 4;
foreach($data as $i=>$n) {
$numbers[$i % $rowcount][] = $n;
}
// OPTIONAL: Join rows together into comma-separated string
$numbers = array_map(function($a) {return implode(",",$a);},$numbers);
$verticallyChunked = array();
$numColumns = 4;
$i = 0;
// optionally pad the array to next largest multiple of the chunksize
// important if you output an html table and like valid well formed html
$totalRows = ceil(count($array) / $numColumns);
$array = array_pad($array, $totalRows * $numColumns, '');
foreach ($array as $val) {
$verticallyChunked[$i++ % $numColumns][] = $val;
}
$arr = array(25,41,120,...36);
How to group values in $arr to specified integer range $start ~ $end ?
For example , if the level range is 1~5(1,2,3,4,5), how can I specify a level for each element of $arr ?
The only principle is that larger value should map to larger level, and should cover the entire level range as possible.
UPDATE
I'll give a maybe over simplified example:
if the levels are 1~4, and the $arr is array(25,41,120,36),then obviously the best way to assign level numbers should be:
25 -> 1
41 -> 3
120 -> 4
36 -> 2
Frist, sort it: http://php.net/manual/en/function.sort.php (and if your array has associative keys, check out asort() )
Then, I would make a new array that would hold your result. Iterate though $arr and if do a check that the value is between your bounds. If it is, add it to the new array.
$NewArray = array();
$arr = sort($arr);
$i = 0;
while ($i < count($arr))
{
if ($arr[$i] <= $HighValue && $arr[$i] >= $LowValue)
{
$NewArray[] = $arr[$i];
}
$i++;
}
Maybe you can try this:
$inputarr = array(1,3,5,7,2,4,6,8);
$levelcount = 3; //assume you have 3 levels
$csize = ceil(count($inputarr)/$levelcount);
sort($inputarr);
print_r(array_chunk($inputarr,$csize,true))
The output is
Array
(
[0] => Array
(
[0] => 1
[1] => 2
[2] => 3
)
[1] => Array
(
[3] => 4
[4] => 5
[5] => 6
)
[2] => Array
(
[6] => 7
[7] => 8
)
)
I do not quite understand how you want to associate the numbers to their level. Presumably you want the number as the key and the level as the value in an associative array. At least that is what your example looked like.
Also, I do not understand the function of $start and $end. If $start is 5 and $end is 50, but there are only 10 numbers, what happens? What if $start is 2 and $end is 7 and there are 10 numbers? I replaced the mechanism with just $levelOffset. It is my guess as to what you really wanted.
<?php
$levelOffset = 1;
$arr = array(25,41,120,36);
sort($arr);
$arr = array_flip($arr);
foreach ($arr as &$level) {
$level += $levelOffset;
}
/*
var_dump($arr) gives:
array(4) {
[25]=>
int(1)
[36]=>
int(2)
[41]=>
int(3)
[120]=>
&int(4)
}
*/