I have this array which stores the values in the array in this format
Array
(
[0] => 0,20
[1] => 21,50
[2] => 201,300
[3] => 301,400
)
now how will I find the smallest and the largest numeric value from it ?
I think you need minimum and maximum range.
For minimum and maximum range, first walk through array and replace
, by . so that they become numbers (comparable).
Them find out min() and max() of the resulting array.
Find out the key where the elements sit.
Now, access the elements of the original array with these keys.
<?php
$org = $result = Array(
'0,20',
'21,50',
'201,300',
'301,400',
);
$result = array_map(function($el) {
return str_replace(',','.',$el); }, $result
);
echo '<pre>';
$minKey = array_search(min($result), $result);
$maxKey = array_search(max($result), $result);
$min2 = $org[$minKey]; // Returns 0,20
$temp = explode(',', $min2);
$min = $temp[0];
echo $min; // Prints 0
echo "<br/>";
$max2 = $org[$maxKey]; // Returns 301,400
$temp = explode(',', $max2);
$max = $temp[1];
echo $max; // Prints 400
?>
Try as below :
$final_array = array();
foreach($a as $val)
{
$exploded_val = explode(",",$val);
$final_array[] = $exploded_val[0];
$final_array[] = $exploded_val[1];
}
sort($final_array);
$min = $final_array[0];
$max = $final_array[count($final_array)-1];
echo $min.'>>'.$max;
Why not using min and max functions?
You should watch out how you store your data... If I understood well, you just need to explode the array values, to mount a proper array and then use max and min functions.
Something like this:
$ar = array("0,20","21,50","201,300","301,400");
foreach ($ar as $el) {
$el = explode(",", $el);
$result[] = $el[0];
$result[] = $el[1];
}
echo "min: ".min($result)."\n";
echo "max: ".max($result);
Related
I have range array in PHP which contain no of range, but i want to marge that all possible rang by around near value ..!
Range array like this :
$array = array('1.10','21.30','31.40','41.50','81.90');
And i want like below after marge :
$array = array('1.10','21.50','81.90');
I tried to merged, but I wanted to find out the result that I did not have.
$dis = array();
$array = array('1.10','21.30','31.40','41.50','81.90');
foreach ($array as $value) {
$ex = explode('.',$value);
if(isset($dis[$ex[1] + 1])){
$dis[$ex[1] + 1][0] = $ex[0];
}else if(isset($dis[$ex[0] - 10])){
$dis[$ex[0] - 10][1] = $ex[1];
}else $dis[$ex[0]] = $ex;
}
$new_array = array();
foreach($dis as $value){
$new_array[] = implode('.',$value)
}
//Output : array('1.10','21.50','41.50','81.90')
Will there be any easy solution for this ?
Yuu... Finally i made this ans and it working fine..!
$dis = array();
$array = array('121.130','101.110','31.40','61.70','1.10','21.30','51.60','81.90','111.120');
sort($array);
foreach($array as $value){
$ex = explode('.',$value);
$no = $ex[0] - 1;
if(isset($dis[$no])){
$dis[$ex[1]] = array($dis[$no][0],$ex[1]);
unset($dis[$no]);
}else $dis[$ex[1]] = $ex;
}
$new_array = array_map(function($v){ return implode('.',$v); }, $dis);
This question already has answers here:
Populate array of integers from a comma-separated string of numbers and hyphenated number ranges
(8 answers)
Closed 6 months ago.
I'm trying to normalize/expand/hydrate/translate a string of numbers as well as hyphen-separated numbers (as range expressions) so that it becomes an array of integer values.
Sample input:
$array = ["1","2","5-10","15-20"];
should become :
$array = [1,2,5,6,7,8,9,10,15,16,17,18,19,20];
The algorithm I'm working on is:
//get the array values with a range in it :
$rangeArray = preg_grep('[-]',$array);
This will contain ["5-10", "16-20"]; Then :
foreach($rangeArray as $index=>$value){
$rangeVal = explode('-',$value);
$convertedArray = range($rangeVal[0],$rangeVal[1]);
}
The converted array will now contain ["5","6","7","8","9","10"];
The problem I now face is that, how do I pop out the value "5-10" in the original array, and insert the values in the $convertedArray, so that I will have the value:
$array = ["1","2",**"5","6","7","8","9","10"**,"16-20"];
How do I insert one or more values in place of the range string? Or is there a cleaner way to convert an array of both numbers and range values to array of properly sequenced numbers?
Here you go.
I tried to minimize the code as much as i can.
Consider the initial array below,
$array = ["1","2","5-10","15-20"];
If you want to create a new array out of it instead $array, change below the first occurance of $array to any name you want,
$array = call_user_func_array('array_merge', array_map(function($value) {
if(1 == count($explode = explode('-', $value, 2))) {
return [(int)$value];
}
return range((int)$explode[0], (int)$explode[1]);
}, $array));
Now, the $array becomes,
$array = [1,2,5,6,7,8,9,10,15,16,17,18,19,20];
Notes:
Casts every transformed member to integer
If 15-20-25 is provided, takes 15-20 into consideration and ignores the rest
If 15a-20b is provided, treated as 15-20, this is result of casing to integer after exploded with -, 15a becomes 15
Casts the array keys to numeric ascending order starting from 0
New array is only sorted if given array is in ascending order of single members and range members combined
Try this:
<?php
$array = ["1","2","5-10","15-20"];
$newdata = array();
foreach($array as $data){
if(strpos($data,'-')){
$range = explode('-', $data);
for($i=$range[0];$i<=$range[1];$i++){
array_push($newdata, $i);
}
}
else{
array_push($newdata, (int)$data);
}
}
echo "<pre>";
print_r($array);
echo "</pre>";
echo "<pre>";
print_r($newdata);
echo "</pre>";
Result:
Array
(
[0] => 1
[1] => 2
[2] => 5-10
[3] => 15-20
)
Array
(
[0] => 1
[1] => 2
[2] => 5
[3] => 6
[4] => 7
[5] => 8
[6] => 9
[7] => 10
[8] => 15
[9] => 16
[10] => 17
[11] => 18
[12] => 19
[13] => 20
)
Problem solved!
Using range and array_merge to handle the non-numeric values:
$array = ["1","2","5-10","15-20"];
$newArray = [];
array_walk(
$array,
function($value) use (&$newArray) {
if (is_numeric($value)) {
$newArray[] = intval($value);
} else {
$newArray = array_merge(
$newArray,
call_user_func_array('range', explode('-', $value))
);
}
}
);
var_dump($newArray);
It's easier to find out the minimum and maximum value and create the array with them. Here's an example:
$in = ["1","2","5-10","15-20"];
$out = normalizeArray($in);
var_dump($out);
function normalizeArray($in)
{
if(is_array($in) && sizeof($in) != 0)
{
$min = null;
$max = null;
foreach($in as $k => $elem)
{
$vals = explode('-', $elem);
foreach($vals as $i => $val)
{
$val = intval($val);
if($min == null || $val < $min)
{
$min = $val;
}
if($max == null || $val > $max)
{
$max = $val;
}
}
}
$out = array();
for($i = $min; $i <= $max; $i++)
{
$out[] = $i;
}
return $out;
}
else
{
return array();
}
}
here you go mate.
<?php
$array = ["1","2","5-10","15-20"];
$newArr = array();
foreach($array as $item){
if(strpos($item, "-")){
$temp = explode("-", $item);
$first = (int) $temp[0];
$last = (int) $temp[1];
for($i = $first; $i<=$last; $i++){
array_push($newArr, $i);
}
}
else
array_push($newArr, $item);
}
print_r($newArr);
?>
Simpler and shorter answer.
See in Ideone
$new_array = array();
foreach($array as $number){
if(strpos($number,'-')){
$range = explode('-', $number);
$new_array = array_merge($new_array, range($range[0],$range[1]));
}
else{
$new_array[] = (int) $number;
}
}
var_dump($new_array);
try this:
$array = ["1","2","5-10","15-20"];
$result = [];
foreach ($array as $a) {
if (strpos($a,"-")!== false){
$tmp = explode("-",$a);
for ($i = $tmp[0]; $i<= $tmp[1]; $i++) $result[] = $i;
} else {
$result[] = $a;
}
}
var_dump($result);
you did not finish a little
$array = ["1","2","5-10","15-20"];
// need to reverse order else index will be incorrect after inserting
$rangeArray = array_reverse( preg_grep('[-]',$array), true);
$convertedArray = $array;
foreach($rangeArray as $index=>$value) {
$rangeVal = explode('-',$value);
array_splice($convertedArray, $index, 1, range($rangeVal[0],$rangeVal[1]));
}
print_r($convertedArray);
$numbers = array("18339993993","18303839303");
foreach($numbers as $number) {
$number = explode(",", $number);
for($i = 0; $i <= count($number); $i++) {
$number = substr($number,1, 10);
echo $number;
}
please i want to remove the first number in every element in the array and replace it with "999" to all the elements in the array.
I want my output to be like this for each element in the array:
$output[0] = "9998339993993"
$output[1] = "9998303839303"
This should work for you:
(Here I go through every element of the array with array_map(). Then I return each element with 999 at the start plus the original value with an offset of 1 which I get with substr())
<?php
$numbers = array("18339993993","18303839303");
$numbers = array_map(function($v){
return "999" . substr($v, 1);
}, $numbers);
print_r($numbers);
?>
Output:
Array ( [0] => 9998339993993 [1] => 9998303839303 )
Closer to the code in the question:
<?php
$numbers = array("18339993993","18303839303");
$numbers_after = array();
foreach ($numbers as $number){
$number = "999" . substr($number, 1);
array_push($numbers_after, $number);
}
print_r ($numbers_after);
?>
Since there was no regex solution:
$numbers = preg_replace('/^\d/', '999', $numbers);
Easy as that.
I have a array like this
array(
45=>5,
42=>4.9,
48=>5,
41=>4.8,
40=>4.9,
34=>4.9,
.....
)
Here index is userid and value is his score.
Now what i want is to achieve percentile for on user for example percentile of 45,48 would be 99 and 42,40,34 would be 97 and 41 would be 94.
How i can achieve this?
Sort the array based on the "score", ascending
Percentile = (Index of an element in the sorted array ) * 100 / (total elements in the array)
Example:
<?php
$array = array(
45=>5,
42=>4.9,
48=>5,
41=>4.8,
40=>4.9,
34=>4.9,
);
print("Unsorted array:<br/>");
print_r($array);
arsort($array);
print("<br/>");
print("Sorted array:<br/>");
print_r($array);
print("<br/>");
$i=0;
$total = count($array);
$percentiles = array();
$previousValue = -1;
$previousPercentile = -1;
foreach ($array as $key => $value) {
echo "\$array[$key] => $value";
if ($previousValue == $value) {
$percentile = $previousPercentile;
} else {
$percentile = 99 - $i*100/$total;
$previousPercentile = $percentile;
}
$percentiles[$key] = $percentile;
$previousValue = $value;
$i++;
}
print("Percentiles:<br/>");
print_r($percentiles);
print("<br/>");
?>
It can be done a lot easier
function procentile($arr, $percentile=0.95){
sort($arr);
return $arr[round($percentile * count($arr) - 1.0-$percentile)];
}
I have wrote this code:
$final = array(
($data[0] - $data[1]),
($data[1] - $data[2]),
($data[2] - $data[3]),
($data[3] - $data[4]),
($data[4] - $data[5]),
($data[5] - $data[6])
);
Some of them will return negative numbers (-13,-42 etc...), how to change the negative ones to 0?
By the way the think i do after is:
$data_string = join(",", $final);
Example: I need to convert it like in the following:
1,3,-14,53,23,-15 => 1,3,0,53,23,0
You can map that:
$zeroed = array_map(function($v) {return max(0, $v);}, $final);
Will set all numbers lower than 0 to 0.
See array_map and max.
Additionally, you can save you some more handwriting with $data:
$final = array_reduce($data, function($v, $w)
{
static $last;
if (null !== $last) $v[] = max(0, $last - $w);
$last = $w;
return $v;
}, array());
$data_string = join(",", $final);
See array_reduce.
Edit: A foreach loop might be easier to follow, I added some comments as well:
// go through all values of data and substract them from each other,
// negative values turned into 0:
$last = NULL; // at first, we don't have a value
$final = array(); // the final array starts empty
foreach($data as $current)
{
$isFirst = $last === NULL; // is this the first value?
$notFirst = !$isFirst;
if ($notFirst)
{
$substraction = $last - $current;
$zeroed = max(0, $substraction);
$final[] = $zeroed;
}
$last = $current; // set last value
}
And here is the demo.
Am guessing this is homework. If so please mark it as such.
Hints:
use a loop instead of hardwired array references.
use an if-statement to check for negative values and switch their sign.
your use of join is correct
I like Hakre's compact answer. However, if you have a more complex requirement, you can use a function:
<?php
$data = array(11,54,25,6,234,9,1);
function getZeroResult($one, $two) {
$result = $one - $two;
$result = $result < 0 ? 0 : $result;
return $result;
}
$final = array(
getZeroResult($data[0], $data[1]),
getZeroResult($data[1], $data[2]),
getZeroResult($data[2], $data[3]),
getZeroResult($data[3], $data[4]),
getZeroResult($data[4], $data[5]),
getZeroResult($data[5], $data[6])
);
print_r($final);
?>
http://codepad.org/viGBYj4f (With an echo to show the $result before test.)
Which gives you:
Array
(
[0] => 0
[1] => 29
[2] => 19
[3] => 0
[4] => 225
[5] => 8
)
Note, you could also just return the ternary:
function getZeroResult($one, $two) {
$result = $one - $two;
return $result < 0 ? 0 : $result;
}
As well as using it in a loop:
<?php
$data = array(11,54,25,6,234,9,1);
function getZeroResult($one, $two) {
$result = $one - $two;
echo "$one - $two = $result\n";
return $result < 0 ? 0 : $result;
}
$c_data = count($data)-1;
$final = array();
for ($i = 0; $i < $c_data; $i++) {
$final[] = getZeroResult($data[$i], $data[$i+1]);
}
print_r($final);
?>
http://codepad.org/31WCbpNr