i have array:
Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 7 )
how to make condition in php when looping i can get output:
$datarange = 1-3,7;
i got logic like this:
if (value of array[0] + 1) = value of array[1] {
$datarange = value of array[0] - value of array[1];
}else{
$datarange = value of array[0] , value of array[1];
}
but i dont know how to Implement that to my looping
Here's a function that will make ranges when possible in an array of numbers.
<?php
function getRange($numbers) {
$lastNumber = null;
$currentRange = [];
$ranges = [];
foreach ($numbers as $number) {
if ($lastNumber === null) { // first iteration, add the number to current range
$currentRange[] = $number;
}
else {
if ($number - $lastNumber === 1) { // if difference with last number is 1, they're consecutive
$currentRange[] = $number;
}
else { // they're not consecutive, finish current range and start a new one
$ranges[] = $currentRange;
$currentRange = [$number];
}
}
$lastNumber = $number; // set the last number to compare with the next
}
$ranges[] = $currentRange; // add last range
$rangesString = []; //
foreach ($ranges as $range) {
$str = $range[0];
if (count($range) > 1) {
$str .= "-".$range[count($range) - 1];
}
$rangesString[] = $str;
}
return implode(", ", $rangesString);
}
echo getRange([1,2,3,7]); // result = 1-3, 7
echo getRange([1,2,6,9,10,12,15,17,18,19]); // result = 1-2, 6, 9-10, 12, 15, 17-19
Try this. I have change your logic and apply it in loop. for range:
$arr = array(1,2,3,7);
$last_val = "";
$first_val = "";
$add_val = true;
foreach ($arr as $key => $value) {
if($first_val == "")
$first_val = $value;
if(isset($arr[$key+1]))
{
if($value+1 == $arr[$key+1])
{
$last_val = $arr[$key+1];
$add_val = false;
}
else
$add_val = true;
}
else
$add_val = true;
if($add_val)
{
if($last_val != "")
$datarange[] = $first_val."-".$last_val;
else
$datarange[] = $first_val;
$first_val = "";
$last_val = "";
}
}
echo implode(",", $datarange);
DEMO
Related
I have this array.
$val = array(12:10, 4:16, 2:05);
I want to subtract 14:00 hrs from the $val array in the way that from every element that element do not become negative like this:
$val = array(0, 2:26, 2:05)
<?php
$input = "14:00";
$val = array("12:10", "4:16", "2:05");
function timeSubtractionFirstTime($actual_time ,$time_to_reduce){
$actual_time_array = explode(":",$actual_time);
$time_to_reduce = explode(":",$time_to_reduce);
$final_result = [];
if($actual_time_array[1] < $time_to_reduce[1]){
$actual_time_array[0] = $actual_time_array[0]-1;
$final_result[] = $actual_time_array[1]+60-$time_to_reduce[1];
}else{
$final_result[] = $actual_time_array[1]-$time_to_reduce[1];
}
$final_result[] = $actual_time_array[0]-$time_to_reduce[0];
return implode(":", array_reverse($final_result));
}
$timeToReduceLeft = $input;
foreach ($val as &$value) {
$diff = timeSubtractionFirstTime($value, $timeToReduceLeft);
if (strpos($diff, chr(45)) !== false){ //if $value < $timeToReduceLeft
$timeToReduceLeft = timeSubtractionFirstTime($timeToReduceLeft, $value);
$value = "00:00";
}
else { //if $value >= $timeToReduceLeft
$value = timeSubtractionFirstTime($value, $timeToReduceLeft);
$timeToReduceLeft = "00:00";
}
if ($timeToReduceLeft == "00:00"){
break;
}
}
echo implode(",", $val);
I get the function to extract time from this post and implement the logic for your problem as follows:
We substract the time from input value until the input value become zero or entire array elements become zero (by forloop).
This solution also works with input or array elements value greater than "24:00".
I created this code so that it will give me five value based on probability. Then insert into an array. It works but I want it to give me 5 unique value. If I used array_unique() it will make the output unique so the end result will be 3 or 2 or sometimes 4 value because it removes duplicates. but I want them to be 5 unique values all the time. How can I do This.
This is my code
<?php
$random= [];
function getRandomWeightedElement(array $weightedValues)
{
$array = array();
foreach ($weightedValues as $key => $weight) {
$array = array_merge(array_fill(0, $weight, $key), $array);
}
return $array[array_rand($array)];
}
global $res;
for($i=0; $i<5 ; $i++)
{
$res=getRandomWeightedElement(array('A'=>0.05, 'B'=>0.05,'C'=>0.10,'D'=>5,'E'=>5,'F'=>5,'G'=>5,'H'=>13,'I'=>16,'J'=>16,'K'=>16.8,'L'=>18));
global $stopAt;
if ($res=='A') {
$stopAt = 20;
} else if ($res=='B') {
$stopAt = 50;
} else if ($res=='C') {
$stopAt = 70;
} else if ($res=='D') {
$stopAt = 100;
} else if ($res=='E') {
$stopAt = 135;
} else if ($res=='F') {
$stopAt = 165;
continue;
} else if ($res=='G') {
$stopAt = 190;
} else if ($res=='H') {
$stopAt = 230;
} else if ($res=='I') {
$stopAt = 265;
} else if ($res=='J') {
$stopAt = 292;
} else if ($res=='K') {
$stopAt = 320;
} else if ($res=='L') {
$stopAt = 350;
} else{
echo "error";
}
$random[]= $stopAt;
}
print_r(array_unique($random));
?>
You will have to check if the value already exists in the result array, you can use in_array() for that. But that means you have to keep looping until you have 5 unique results which means changing the loop.
$random= [];
function getRandomWeightedElement(array $weightedValues)
{
$array = array();
foreach ($weightedValues as $key => $weight) {
$array = array_merge(array_fill(0, $weight, $key), $array);
}
return $array[array_rand($array)];
}
//for($i=0; $i<5 ; $i++) {
$params = array('A'=>0.05, 'B'=>0.05,'C'=>0.10,'D'=>5,
'E'=>5,'F'=>5,'G'=>5,'H'=>13,'I'=>16,
'J'=>16,'K'=>16.8,'L'=>18);
$notGot5 = true;
while ( $notGot5 ) {
$res=getRandomWeightedElement($params);
if ($res=='A') {
$stopAt = 20;
} else if ($res=='B') {
$stopAt = 50;
} else if ($res=='C') {
$stopAt = 70;
} else if ($res=='D') {
$stopAt = 100;
} else if ($res=='E') {
$stopAt = 135;
} else if ($res=='F') {
$stopAt = 165;
continue;
} else if ($res=='G') {
$stopAt = 190;
} else if ($res=='H') {
$stopAt = 230;
} else if ($res=='I') {
$stopAt = 265;
} else if ($res=='J') {
$stopAt = 292;
} else if ($res=='K') {
$stopAt = 320;
} else if ($res=='L') {
$stopAt = 350;
} else{
echo "error";
}
if ( in_array($stopAt, $random) ) {
// keep looking
continue;
} else {
$random[]= $stopAt;
}
// loop terminates when we have 5 in the array
$notGot5 = count($randon) != 5;
}
print_r($random);
Instead of doing several if statements to choose random values, you can choose the values directly from the array itself.
The below code should give you what you want:
$valuesToChooseFrom = [
'A' => 0.1,
'B' => 0.3,
'C' => 3.1,
'D' => 20,
'E' => 10,
'F' => 4,
'G' => 222
];
$result = [];
for ($i = 0; $i < 5; $i++) {
$key = array_rand($valuesToChooseFrom);
$result[$key] = $valuesToChooseFrom[$key];
unset($valuesToChooseFrom[$key]);
}
print_r($result);
And gives:
Array
(
[F] => 4
[G] => 222
[D] => 20
[B] => 0.3
[E] => 10
)
It works by selecting a random element from the valuesToChooseFrom array, using the array_rand() function. The array_rand function selects a random element from the array you pass it, and returns that element (the key in this case, since we are working with a 2 dimensional array). You then add an item to the result array, with the key being the key returned from the array_rand call, and the value being the value in the valuesToChooseFrom array, using the key to index the valuesToChooseFrom array.
To prevent PHP from choosing the same value more than once, you have to remove the value valuesToChooseFrom array. This is what the unset($valuesToChooseFrom[$key]); line does.
array_rand() also accepts a second argument, which is the number of random elements to select from the array. If you pass in 5 as the second argument, it will choose 5 random elements from the array. And since they all appear to be unique (I could be mistaken), a better way would be to do array_random($valuesToChooseFrom, 5) to select 5 random values from the array.
But since that method only returns the keys, you will need to do a foreach loop to loop over the returned array, and then use each key to grab the value from the valuesToChooseFrom array.
how to create a function counts the number of adjacent elements and returns it. if the count of elements is the same, it will return an earlier index element, for example:
$arr = array(-1,-1,-1,9,9,9,-2,7,9);
$result = adjacentElement($arr);
echo $result //it wiill return -1
the count of values -2 and 9 are the same = 3,
then the function will return the value -1, because the index is earlier.
My Best code
<?php
function arrayCountAdjacent($array) {
$adjacentArray = array();
$lastValue = null;
$i = 0;
$count = 0;
foreach ($array as $key => $value) {
if ($lastValue === null || $lastValue != $value) {
$i++;
$adjacentArray[$i] = array("value" => $value, "count" => 1);
$lastValue = $value;
}
else {
$adjacentArray[$i]["count"]++;
}
}
return $adjacentArray;
}
$a = array(-1,-1,-1,9,9,9,-2,7,9)//return -1;
//$b = array(-2,-2,-2,9,9,9,9,-2,7,9); //return 9
//$c = array(-2,-2,-2,9,9,-2,9,9,9,-2,9,9,9,7,9,9); //return -2
$count = arrayCountAdjacent($a);
foreach(arrayCountAdjacent($a) as $result)
{
echo "value = " . $result['value']."\n";
}
the output
value = -1
value = 9
value = -1
value = 7
value = 9
expectation
value = - 1
I have a array to find sequence of alphabets and then fetch last and first combination. I am trying something like this.
$aarr = ['x','y','z','t','m','n','x','y','z'];
$str = implode('',$aarr);
$all_subset = powerSet($aarr);
foreach ($all_subset as $set) {
$sre_temp = implode('', $set);
$tru = hasOrderedCharactersForward($sre_temp);
if($tru){
echo $sre_temp.'<br>';
}
}
function powerSet($array) {
// add the empty set
$results = array(array());
foreach ($array as $element) {
foreach ($results as $combination) {
$results[] = array_merge(array($element), $combination);
}
}
return $results;
}
function hasOrderedCharactersForward($str, $i = 2) {
$alpha = 'abcdefghijklmnopqrstuvwxyz';
$len = strlen($str);
for($j=0; $j <= $len - $i; $j++){
if(strrpos($alpha, substr($str, $j, $i)) !== false){
return true;
}
}
return false;
}
I think powerSet() is not working like i think. Even it should show 'xyz' as combination but its not;
Have a look at this and make use of it if it fits your needs.
$aarr = ['x','y','z','t','m','n','x','y','z'];
$subsets = [];
$i=0;
#here we merge all chars to sub-sequence
foreach($aarr as $k=>$v){
$subsets[$i][]=$v;
if(isset($aarr[$k+1]) && ord($v)+1!==ord($aarr[$k+1])){
$i++;
}
}
$subsets = array_map(function($a){ return implode('',$a);},$subsets);
print_r($subsets);
Result:
Array ( [0] => xyz [1] => t [2] => mn [3] => xyz )
Getting the first and last value:
#get first
$first=null;
$i=0;
do{
if(strlen($subsets[$i])>1){#find sequence
$first = $subsets[$i];
}
$i++;
}while(!$first && isset($subsets[$i]));
#get last
$last=null;
$i=count($subsets)-1;
do{
if(strlen($subsets[$i])>1){#find sequence
$last = $subsets[$i];
}
$i--;
}while(!$last && isset($subsets[$i]));
print "$first, $last";
Result:
xyz, xyz
I have an array that has been sorted from low to high which has over 260k values in. I have found out the mean(average) and median of the array just need to find out the mode?
I cannot use any mathematical functions that PHP has, it has to be all done manually.
I would like it so there could be just one value that is the mode but then there can be multiple values that can be the mode. I also need to be able to record the number of times that the value is stored. For example the number 51 appears 6 times so I can print both values.
This is my code so far:
$amountRecords = 0;
$totalValue = 0;
$valueArray = array();
// reads in csv file
$handle = fopen('Task1-DataForMeanMedianMode.csv', 'r');
// to skip the header names/values
fgetcsv($handle);
// creates array containing variables of csv file in ascending order
while(($row = fgetcsv($handle, "\r")) != FALSE)
{
// if amountRecords equals 0
if($amountRecords == 0)
{
// adds value from csv to array
$valueArray[] = $row[1];
} // else amountRecords does not equal 0
else
{
// if the value in array location before is greater than the current value from the csv file
if($valueArray[$amountRecords - 1] > $row[1])
{
// the current array location becomes the one in the location before
$valueArray[] = $valueArray[$amountRecords - 1];
// add the value from the csv to the location before
$valueArray[$amountRecords - 1] = $row[1];
} // if the value in the location before is not greater than the current value in the csv file
else
{
// adds value from csv to array
$valueArray[] = $row[1];
}
}
// calculates the total value of the values in csv file
$totalValue = $totalValue + $row[1];
// calculates the number of values in the csv file
$amountRecords++;
}
// calculate average value of payments
$averageValue = $totalValue / $amountRecords;
// limit integer to 2 decimal place
$average = number_format($averageValue,2,'.','');
// finds middle value
$middle = floor(($amountRecords / 2) - 1);
// calculates the median value
// if array size is even
if($amountRecords % 2 == 0)
{
// calculates median
$median = $valueArray[$middle];
}
else // if array size is odd
{
// calculate low and high values
$low = $valueArray[$middle];
$high = $valueArray[$middle + 1];
// calculates median
$median = (($low + $high) / 2);
}
// works out mode
// creates array count
$count = array();
// for each value in the valueArray
foreach( $valueArray as $value )
{
if( isset( $count[$value] ))
{
$count[$value]++;
}
else
{
$count[$value] = 1;
}
}
$mostCommon = "";
$iter = 0;
foreach( $count as $k => $v )
{
if( $v > $iter )
{
$mostCommon = $k;
$iter = $v;
}
}
$modeArray = array( "mode" => $mostCommon , "count" => $iter );
The mode of a numerical set is the number that occurs the most often. You can do this with PHP using code similar to the following:
$values = array_count_values($valueArray);
$mode = array_search(max($values), $values);
Simple!
$arr = array(4,6,7,1,4,7,4,7,1);
$freq = array();
for($i=0; $i<count($arr); $i++)
{
if(isset($freq[$arr[$i]])==false)
{
$freq[$arr[$i]] = 1;
}
else
{
$freq[$arr[$i]]++;
}
}
$maxs = array_keys($freq, max($freq));
for($i=0; $i<count($maxs); $i++)
{
echo $maxs[$i] . ' ' . $freq[$maxs[$i]];
echo '<br />';
}
Mathematical only solution:
//sample data
$dataArr = ["1", "3", "5", "1", "3", "7", "1", "8", "1"];
//a multidimensional array to hold the keys (extracted fro above) and their values (number of occurrences)
$multiDArr = [];
for ($i = 0; $i < count($dataArr); $i++) {
$key = $dataArr[$i];
if (isset($multiDArr[$key])) {
//key already exists; increment count of its value
$multiDArr[$key] = $multiDArr[$key] + 1;
} else {
//key does nto exist; add it and an inital value of 1
$multiDArr[$key] = 1;
}
}
$highestOccuring = 0;
$highestOccuringKey = null;
foreach ($multiDArr as $key => $value) {
if ($value > $highestOccuring) {
$highestOccuring = $value;
$highestOccuringKey = $key;
}
}
echo "MODE / highest occuring key: " . $highestOccuringKey;
/** find array mode, most often see value
* #param list(int) $a_in
* #return list(int)
*/
function array_mode(array $a_in): array{
$a_freq = [];
foreach( $a_in as $v ) {
if (!isset($a_freq[$v])) {
$a_freq[$v] = 0;
}
$a_freq[$v]++;
}
$a_maxs = array_keys($a_freq, max($a_freq));
return $a_maxs;
}
// test code
$a_in = [4,6,7,1,4,7,4,7,1];
array_mode( $a_in);
This will take values and turn it into an array of the modes. For Example: print_r(get_mode(1,2,2,3,3,3,4,4,5,5,5,6,7,8,9)); will return,
Array
(
[0] => Array
(
[value] => 3
[count] => 3
)
[1] => Array
(
[value] => 5
[count] => 3
)
)
code:
function get_mode(...$inputArray){
$max=0;
return array_reduce(
array_values(array_reduce(array_values($inputArray),function($talliedArray,$inputNode){
if(isset($talliedArray[(string)$inputNode]))
$talliedArray[(string)$inputNode]['count']++;
else
$talliedArray[(string)$inputNode] = [
'value' => $inputNode,
'count' => 1
];
return $talliedArray;
},[])),function($modeArray,$talliedNode)use(&$max){
if($talliedNode['count'] < $max) return $modeArray;
if($talliedNode['count']=== $max) return array_merge($modeArray,[$talliedNode]);
//if count > $max
$max = $talliedNode['count'];
return [$talliedNode];
},[]);
}
This satisfies the "no math functions", the "multiple return modes" and the "have the value and number of occurrences returned".
This will only really work with strings and numbers. It will go weird with booleans, Objects and Arrays.