Related
I have this array with year as its key and count as its value,
$dateRange = array([
"1990" => 10,
"1991" => 12,
"1992" => 12,
"1993" => 12,
"1994" => 12,
"1995" => 12,
"1996" => 6
]);
and how can I make it look like this *(getting consecutive year/s with a count/value of 12 then count its total value)
$dateRange = ([
"1990" => 10,
"1991-1995" => 60,
"1996" => 6
]);
I came up with the following solutions, it's not efficient with large data but will work.
1991-1995 will be string though.
$dateRange = array([
1990 => 10,
1991 => 12,
1992 => 12,
1993 => 12,
1994 => 12,
1995 => 12,
1996 => 6
]);
dump($dateRange[0]);
$first = reset($dateRange[0]);
$last = end($dateRange[0]);
$newArr = array([]);
$sum = 0;
$firstRange = null;
$lastRange = null;
foreach($dateRange[0] as $key => $item){
if($item == $first){
$newArr[0][$key] = $item;
}
elseif($item == $last){
$newArr[0][$firstRange.'-'.$lastRange] = $sum;
$newArr[0][$key] = $item;
}
else{
if($firstRange == null){
$firstRange = $key;
}
$lastRange = $key;
$sum += $item;
}
}
dd($newArr[0]);
Loop through each individual dataset(subarray) and
Sort the keys numerically.
Compare every current key with previous key to check if they are consecutive.
If prev_key + 1 == curr_key, then they are consecutive, else they are not.
Check the same for their values' equality as well.
In either step 2 or 3, if any of the conditions don't match, add the current range and it's sum to the result and start a new range from this index. Likewise, collect all the results.
Snippet:
<?php
$res = [];
foreach($dateRange as $k => $v){
$temp = [];
$keys = array_keys($v);
sort($keys, SORT_NUMERIC);
$prev = 0;
$sum = 0;
for($i = 0; $i < count($keys); ++$i){
if($i > 0 && ($keys[ $i - 1 ] + 1 != $keys[ $i ] || $v[ $keys[ $i - 1 ] ] !== $v[ $keys[ $i ] ])){
if($prev == $i - 1) $temp[ $keys[ $prev ]] = $sum;
else $temp[ $keys[$prev] . "-" . $keys[$i - 1]] = $sum;
$sum = 0;
$prev = $i;
}
$sum += $v[$keys[ $i ]];
if($i === count($keys) - 1){
if($prev == $i) $temp[ $keys[ $prev ]] = $sum;
else $temp[ $keys[$prev] . "-" . $keys[ $i ]] = $sum;
}
}
$res[] = $temp;
}
print_r($res);
Online Demo
Here is a more Laravel friendly solution using Framework collection methods.
Using Collection is more readable and more understandable.
$dateRange = [
[
"1990" => 10,
"1991" => 12,
"1992" => 12,
"1993" => 12,
"1994" => 12,
"1995" => 12,
"1996" => 6,
],
];
collect($dateRange)->map(function ($range)
{
return collect($range)->groupBy(function ($item)
{
return $item;
}, true)->mapWithKeys(function (Collection $item)
{
$sorted = $item->sortKeys();
$keys = $sorted->keys();
$firstYear = $keys->first();
$lastYear = $keys->last();
$sum = $item->sum();
return [($firstYear != $lastYear ? $firstYear.'-'.$lastYear : $firstYear) => $sum];
});
})->dd();
Output:
array:1 [▼
0 => Illuminate\Support\Collection {#2259 ▶
#items: array:3 [▶
1990 => 10
"1991-1995" => 60
1996 => 6
]
#escapeWhenCastingToString: false
}
]
$dateRange = [
'1990' => 10,
'1991' => 12,
'1992' => 12,
'1993' => 12,
'1994' => 12,
'1995' => 12,
'1996' => 6
];
ksort($dateRange);
$previousValue = '';
$result = [];
array_walk(
$dateRange,
function (int $value, string $key) use (&$previousValue, &$result) {
if ($previousValue === $value) {
$lastKey = array_key_last($result);
$result[substr($lastKey, 0, 4) . '-' . $key] = $result[$lastKey] + $value;
unset($result[$lastKey]);
} else {
$result[$key] = $value;
}
$previousValue = $value;
},
[]
);
print_r($result);
You have an array of arrays here. You could just do $dateRange = [...]; but I'll assume this is what you intended.
$dateRange = array([
"1990" => 10,
"1991" => 12,
"1992" => 12,
"1993" => 12,
"1994" => 12,
"1995" => 12,
"1996" => 6
]);
Using Collection methods, it should be easy.
$collection = collect($dateRange[0]);
$keys = $collection->keys();
$newKeys = [
$keys->shift(), // remove and return first key of $keys (1990)
$keys->pop(), // remove and return last key of $keys (1996)
"{$keys->first()}-{$keys->last()}", // concat first key and last key of $keys ("1991-1995")
];
// $newKeys is now equal to [1990, "1991-1995", 1996]
$newValues = [
0 => $collection->pull($newKeys[0]), // remove and return element 1990 from collection (10)
2 => $collection->pull($newKeys[1]), // remove and return element 1996 from collection (6)
1 => $collection->sum(), // return sum of remaining elements in collection (60)
];
ksort($newValues); // sort $newValues by its key (this is why I specified them in the order 0, 2, 1).
// $newValues is equal to [10, 60, 6]
$newArray = array_combine($newKeys, $newValues); // create a new array from $newKeys and $newValues
This question already has answers here:
PHP getting a value where key is between a range
(3 answers)
Closed 5 months ago.
I'd like to create an array with some keys will be a range of data.
Example:
$data = [
1 => 1000,
2 => 500,
3 => 250,
4 - 5 => 100,
6 - 10 => 50,
11 - 99 => 20
];
In this case, $data[4] should return 100. $data[53] should return 20, etc.
Is this possible without typing everything?
Thanks
Using array_fill():
<?php
$data = [
1 => 1000,
2 => 500,
3 => 250
];
$a = array_fill(4,2, 100);
$b = array_fill(6,5, 50);
$c = array_fill(11,89, 20);
$data = $data + $a + $b + $c;
print_r($data);
Naive solution without array_fill(). Memory efficient way.
<?php
function array_search_key_range(int $needle, array $haystack)
{
foreach ($haystack as $range => $value) {
[$min, $max] = array_map('intval', explode('-', (string)$range, 2) + [1 => $range]);
if ($min <= $needle && $needle <= $max) {
return $value;
}
}
return false;
}
$data = [
1 => 1000,
2 => 500,
3 => 250,
'4-5' => 100,
'6-10' => 50,
'11-99' => 20,
];
var_dump(array_search_key_range(2, $data)); // 500
var_dump(array_search_key_range(4, $data)); // 100
var_dump(array_search_key_range(10, $data)); // 50
var_dump(array_search_key_range(98, $data)); // 20
var_dump(array_search_key_range(120, $data)); // false
Well,
a bit clumsy but you might consider the following:
$data = array_merge([
0 => null,
1 => 1000,
2 => 500,
3 => 250,
],
array_map(function(){ return 100;}, range(4,5)),
array_map(function(){ return 50;}, range(6,10)),
array_map(function(){ return 20;}, range(11,99))
);
<?php
$data = [
'1' => 1000,
'2' => 500,
'3' => 250,
'4-5' => 100,
'6-10' => 50,
'11-99' => 20];
//Create a new array ($range_arr where you
//create a key for every item in the range specified by your key
//in your $data array
$range_arr = [];
foreach(array_keys($data) as $key) {
$exploded_key = explode('-', $key);
$start_range = $exploded_key[0];
$end_range = $start_range;
if (isset($exploded_key[1])) {
$end_range = $exploded_key[1];
}
foreach(range($start_range,$end_range) as $nr) {
$range_arr[$nr] = $data[$key];
}
}
//for example will output 50
echo $range_arr[7];
If I have an average score of:
$average = 95.00000000
And I have an array:
$grades = array("91-100"=>"A+","80-89"=>"A","70-79"=>"B","60-69"=>"C","50-59"=>"D","0-49"=>"F");
When I try to get an average grade by doing:
$grade = $grades[$average];
I get an error:
Notice: Undefined index: 95.00000000
I think the issue comes from the the key's of the array, but is there a way to do what i'm trying to achieve?
You have to iterate over the keys, and check if your value is between them :
$grades = array("91-100"=>"A+","80-89"=>"A","70-79"=>"B","60-69"=>"C","50-59"=>"D","0-49"=>"F");
$average = 95.00000000 ;
$grade = '' ;
foreach ($grades as $val => $cur_grade) {
list($min, $max) = explode('-', $val); // split key into min and max
if ($average >= $min && $average <= $max) { // compare
$grade = $cur_grade ; // get the value
break ; // stop the loop
}
}
echo $grade ;
Will outputs :
A+
Note that if your $average is not in the range (ex. 69.9), it will match will no case. So you could use "90-100", "80-90", ...
$grades = array("90-100"=>"A+","80-90"=>"A","70-80"=>"B","60-70"=>"C","50-60"=>"D","0-50"=>"F");
$average = 69.9 ;
// ..code above..
echo $grade ; // Outputs "C"
And
$average = 70.0 ;
// ..code above..
echo $grade ; // Outputs "B"
I would suggest changing the grade array to a simpler structure, thus you would get a simpler and more predictable code
<?php
$average = 95.00000000;
$grades = array(
array(
'grade' => 'A+',
'max' => 100,
'min' => 90
),
array(
'grade' => 'A',
'max' => 89,
'min' => 80
),
array(
'grade' => 'B',
'max' => 79,
'min' => 70
),
array(
'grade' => 'C',
'max' => 69,
'min' => 60
),
array(
'grade' => 'D',
'max' => 59,
'min' => 50
),
array(
'grade' => 'F',
'max' => 49,
'min' => 0
),
);
$result = null;
$averageScore = (int) floor($average); // it's better to compare int to int instead of float to int
foreach($grades as $grade) {
if ($average < $grade['max'] && $average >= $grade['min']) {
$result = $grade['grade'];
break;
}
}
if ($result !== null) {
echo 'Your grade is: ' . $result;
} else {
echo 'Grading error, please ask your professor for details!';
}
Using PHP, I'd like to convert a string containing a Roman number into its integer representation. I need this because I need to make calculations on them.
Wikipedia on Roman numerals
It would suffice to only recognize the basic Roman numeral characters, like:
$roman_values=array(
'I' => 1,
'V' => 5,
'X' => 10,
'L' => 50,
'C' => 100,
'D' => 500,
'M' => 1000,
);
That means the highest possible number is 3999 (MMMCMXCIX). I will use N to represent zero, other than that only positive integers are supported.
I cannot use the PEAR library for Roman numbers.
I found this great question on SO on how to test whether the string contains a valid Roman numeral:
How do you match only valid roman numerals with a regular expression?
What would be the best way of coding this?
How about this:
$romans = array(
'M' => 1000,
'CM' => 900,
'D' => 500,
'CD' => 400,
'C' => 100,
'XC' => 90,
'L' => 50,
'XL' => 40,
'X' => 10,
'IX' => 9,
'V' => 5,
'IV' => 4,
'I' => 1,
);
$roman = 'MMMCMXCIX';
$result = 0;
foreach ($romans as $key => $value) {
while (strpos($roman, $key) === 0) {
$result += $value;
$roman = substr($roman, strlen($key));
}
}
echo $result;
which should output 3999 for the supplied $roman. It seems to work for my limited testing:
MCMXC = 1990
MM = 2000
MMXI = 2011
MCMLXXV = 1975
You might want to do some validation first as well :-)
I am not sure whether you've got ZF or not, but in case you (or any of you who's reading this) do here is my snippet:
$number = new Zend_Measure_Number('MCMLXXV', Zend_Measure_Number::ROMAN);
$number->convertTo (Zend_Measure_Number::DECIMAL);
echo $number->getValue();
Zend_Measure_Number on framework.zend.com
This is the one I came up with, I added the validity check as well.
class RomanNumber {
//array of roman values
public static $roman_values=array(
'I' => 1, 'V' => 5,
'X' => 10, 'L' => 50,
'C' => 100, 'D' => 500,
'M' => 1000,
);
//values that should evaluate as 0
public static $roman_zero=array('N', 'nulla');
//Regex - checking for valid Roman numerals
public static $roman_regex='/^M{0,3}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})$/';
//Roman numeral validation function - is the string a valid Roman Number?
static function IsRomanNumber($roman) {
return preg_match(self::$roman_regex, $roman) > 0;
}
//Conversion: Roman Numeral to Integer
static function Roman2Int ($roman) {
//checking for zero values
if (in_array($roman, self::$roman_zero)) {
return 0;
}
//validating string
if (!self::IsRomanNumber($roman)) {
return false;
}
$values=self::$roman_values;
$result = 0;
//iterating through characters LTR
for ($i = 0, $length = strlen($roman); $i < $length; $i++) {
//getting value of current char
$value = $values[$roman[$i]];
//getting value of next char - null if there is no next char
$nextvalue = !isset($roman[$i + 1]) ? null : $values[$roman[$i + 1]];
//adding/subtracting value from result based on $nextvalue
$result += (!is_null($nextvalue) && $nextvalue > $value) ? -$value : $value;
}
return $result;
}
}
Quick idea - go through the Roman number from right to left, if value of $current (more to the left) is smaller than $previous, then subtract it from the result, if larger, then add it.
$romanValues=array(
'I' => 1,
'V' => 5,
'X' => 10,
'L' => 50,
'C' => 100,
'D' => 500,
'M' => 1000,
);
$roman = 'MMMCMXCIX';
// RTL
$arabic = 0;
$prev = null;
for ( $n = strlen($roman) - 1; $n >= 0; --$n ) {
$curr = $roman[$n];
if ( is_null($prev) ) {
$arabic += $romanValues[$roman[$n]];
} else {
$arabic += $romanValues[$prev] > $romanValues[$curr] ? -$romanValues[$curr] : +$romanValues[$curr];
}
$prev = $curr;
}
echo $arabic, "\n";
// LTR
$arabic = 0;
$romanLength = strlen($roman);
for ( $n = 0; $n < $romanLength; ++$n ) {
if ( $n === $romanLength - 1 ) {
$arabic += $romanValues[$roman[$n]];
} else {
$arabic += $romanValues[$roman[$n]] < $romanValues[$roman[$n+1]] ? -$romanValues[$roman[$n]] : +$romanValues[$roman[$n]];
}
}
echo $arabic, "\n";
Some validation of roman number should also be added, though you said that you already have found how to do it.
Copyrights is for this blog (btw!)
http://scriptsense.blogspot.com/2010/03/php-function-number-to-roman-and-roman.html
<?php
function roman2number($roman){
$conv = array(
array("letter" => 'I', "number" => 1),
array("letter" => 'V', "number" => 5),
array("letter" => 'X', "number" => 10),
array("letter" => 'L', "number" => 50),
array("letter" => 'C', "number" => 100),
array("letter" => 'D', "number" => 500),
array("letter" => 'M', "number" => 1000),
array("letter" => 0, "number" => 0)
);
$arabic = 0;
$state = 0;
$sidx = 0;
$len = strlen($roman);
while ($len >= 0) {
$i = 0;
$sidx = $len;
while ($conv[$i]['number'] > 0) {
if (strtoupper(#$roman[$sidx]) == $conv[$i]['letter']) {
if ($state > $conv[$i]['number']) {
$arabic -= $conv[$i]['number'];
} else {
$arabic += $conv[$i]['number'];
$state = $conv[$i]['number'];
}
}
$i++;
}
$len--;
}
return($arabic);
}
function number2roman($num,$isUpper=true) {
$n = intval($num);
$res = '';
/*** roman_numerals array ***/
$roman_numerals = array(
'M' => 1000,
'CM' => 900,
'D' => 500,
'CD' => 400,
'C' => 100,
'XC' => 90,
'L' => 50,
'XL' => 40,
'X' => 10,
'IX' => 9,
'V' => 5,
'IV' => 4,
'I' => 1
);
foreach ($roman_numerals as $roman => $number)
{
/*** divide to get matches ***/
$matches = intval($n / $number);
/*** assign the roman char * $matches ***/
$res .= str_repeat($roman, $matches);
/*** substract from the number ***/
$n = $n % $number;
}
/*** return the res ***/
if($isUpper) return $res;
else return strtolower($res);
}
/* TEST */
echo $s=number2roman(1965,true);
echo "\n and bacK:\n";
echo roman2number($s);
?>
I'm late to the party, but here's mine. Assumes valid Numerals in the string, but doesn't test for a valid Roman number, whatever that is...there doesn't seem to be a consensus. This function will work for Roman numbers like VC (95), or MIM (1999), or MMMMMM (6000).
function roman2dec( $roman ) {
$numbers = array(
'I' => 1,
'V' => 5,
'X' => 10,
'L' => 50,
'C' => 100,
'D' => 500,
'M' => 1000,
);
$roman = strtoupper( $roman );
$length = strlen( $roman );
$counter = 0;
$dec = 0;
while ( $counter < $length ) {
if ( ( $counter + 1 < $length ) && ( $numbers[$roman[$counter]] < $numbers[$roman[$counter + 1]] ) ) {
$dec += $numbers[$roman[$counter + 1]] - $numbers[$roman[$counter]];
$counter += 2;
} else {
$dec += $numbers[$roman[$counter]];
$counter++;
}
}
return $dec;
}
Whew! Those are quite a few answers, and made of them are code-heavy! How about we define an algorithm for this first, before I give an answer?
The Basics
Don't store multi-digit Roman numerals, like 'CM' => 900, or anything like that in an array. If you know that M - C (1000 - 100) equals 900, then ultimately, you should only be storing the values of 1000 and 100. You wouldn't have multi-digit Roman numerals like CMI for 901, would you? Any answer that does this will be inefficient from one that understands the Roman syntax.
The Algorithm
Example: LIX (59)
Do a for loop on the numbers, starting at the end of the string of Roman numerals. In our example: We start on "X".
Greater-Than-Equal-To Case — If the value we are looking at is the same or greater than the last value, simply add it to a cumulative result. In our example: $result += $numeral_values["X"].
Less-Than Case — If the value we are subtracting is less than the previous number, we subtract it from our cumulative result. In our example IX, I is 1 and X is 10, so, since 1 is less than 10, we subtract it: giving us 9.
The Demo
Full Working Demo Online
The Code
function RomanNumeralValues() {
return [
'I'=>1,
'V'=>5,
'X'=>10,
'L'=>50,
'C'=>100,
'D'=>500,
'M'=>1000,
];
}
function ConvertRomanNumeralToArabic($input_roman){
$input_length = strlen($input_roman);
if($input_length === 0) {
return $result;
}
$roman_numerals = RomanNumeralValues();
$current_pointer = 1;
$result = 0;
for($i = $input_length - 1; $i > -1; $i--){
$letter = $input_roman[$i];
$letter_value = $roman_numerals[$letter];
if($letter_value === $current_pointer) {
$result += $letter_value;
} elseif ($letter_value < $current_pointer) {
$result -= $letter_value;
} else {
$result += $letter_value;
$current_pointer = $letter_value;
}
}
return $result;
}
print ConvertRomanNumeralToArabic("LIX");
function romanToInt($s) {
$array = ["I"=>1,"V"=>5,"X"=>10,"L"=>50,"C"=>100,"D"=>500,"M"=>1000];
$sum = 0;
for ($i = 0; $i < strlen($s); $i++){
$curr = $s[$i];
$next = $s[$i+1];
if ($array[$curr] < $array[$next]) {
$sum += $array[$next] - $array[$curr];
$i++;
} else {
$sum += $array[$curr];
}
}
return $sum;
}
Define your own schema! (optional)
function rom2arab($rom,$letters=array()){
if(empty($letters)){
$letters=array('M'=>1000,
'D'=>500,
'C'=>100,
'L'=>50,
'X'=>10,
'V'=>5,
'I'=>1);
}else{
arsort($letters);
}
$arab=0;
foreach($letters as $L=>$V){
while(strpos($rom,$L)!==false){
$l=$rom[0];
$rom=substr($rom,1);
$m=$l==$L?1:-1;
$arab += $letters[$l]*$m;
}
}
return $arab;
}
Inspired by andyb's answer
I just wrote this in about 10 mins, it's not perfect, but seems to work for the few test cases I've given it. I'm not enforcing what values are allowed to be subtracted from what, this is just a basic loop that compares the current letter value with the next one in the sequence (if it exists) and then either adds the value or adds the subtracted amount to the total:
$roman = strtolower($_GET['roman']);
$values = array(
'i' => 1,
'v' => 5,
'x' => 10,
'l' => 50,
'c' => 100,
'd' => 500,
'm' => 1000,
);
$total = 0;
for($i=0; $i<strlen($roman); $i++)
{
$v = $values[substr($roman, $i, 1)];
$v2 = ($i < strlen($roman))?$values[substr($roman, $i+1, 1)]:0;
if($v2 && $v < $v2)
{
$total += ($v2 - $v);
$i++;
}
else
$total += $v;
}
echo $total;
Just stumbled across this beauty and have to post it all over:
function roman($N)
{
$c = 'IVXLCDM';
for ($a = 5, $b = $s = ''; $N; $b++, $a ^= 7)
{
for (
$o = $N % $a, $N = $N / $a ^ 0;
$o--;
$s = $c[$o > 2 ? $b + $N - ($N &= -2) + $o = 1 : $b] . $s
);
}
return $s;
}
function Romannumeraltonumber($input_roman){
$di=array('I'=>1,
'V'=>5,
'X'=>10,
'L'=>50,
'C'=>100,
'D'=>500,
'M'=>1000);
$result=0;
if($input_roman=='') return $result;
//LTR
for($i=0;$i<strlen($input_roman);$i++){
$result=(($i+1)<strlen($input_roman) and
$di[$input_roman[$i]]<$di[$input_roman[$i+1]])?($result-$di[$input_roman[$i]])
:($result+$di[$input_roman[$i]]);
}
return $result;
}
function rom_to_arabic($number) {
$symbols = array(
'M' => 1000,
'D' => 500,
'C' => 100,
'L' => 50,
'X' => 10,
'V' => 5,
'I' => 1);
$a = str_split($number);
$i = 0;
$temp = 0;
$value = 0;
$q = count($a);
while($i < $q) {
$thys = $symbols[$a[$i]];
if(isset($a[$i +1])) {
$next = $symbols[$a[$i +1]];
} else {
$next = 0;
}
if($thys < $next) {
$value -= $thys;
} else {
$value += $thys;
}
$temp = $thys;
$i++;
}
return $value;
}
function parseRomanNumerals($input)
{
$roman_val = '';
$roman_length = strlen($input);
$result_roman = 0;
for ($x = 0; $x <= $roman_length; $x++) {
$roman_val_prev = $roman_val;
$roman_numeral = substr($input, $roman_length-$x,1);
switch ($roman_numeral) {
case "M":
$roman_val = 1000;
break;
case "D":
$roman_val = 500;
break;
case "C":
$roman_val = 100;
break;
case "L":
$roman_val = 50;
break;
case "X":
$roman_val = 10;
break;
case "V":
$roman_val = 5;
break;
case "I":
$roman_val = 1;
break;
default:
$roman_val = 0;
}
if ($roman_val_prev<$roman_val) {
$result_roman = $result_roman - $roman_val;
}
else {
$result_roman = $result_roman + $roman_val;
}
}
return abs($result_roman);
}
I have an array like this:
array (0 =>
array (
'id' => '20110209172713',
'Date' => '2011-02-09',
'Weight' => '200',
),
1 =>
array (
'id' => '20110209172747',
'Date' => '2011-02-09',
'Weight' => '180',
),
2 =>
array (
'id' => '20110209172827',
'Date' => '2011-02-09',
'Weight' => '175',
),
3 =>
array (
'id' => '20110211204433',
'Date' => '2011-02-11',
'Weight' => '195',
),
)
I need to extract minimal and maximal Weight values.
In this example
$min_value = 175
$max_value = 200
Any help on how to do this ?
Thank you !
Option 1. First you map the array to get those numbers (and not the full details):
$numbers = array_column($array, 'weight')
Then you get the min and max:
$min = min($numbers);
$max = max($numbers);
Option 2. (Only if you don't have PHP 5.5 or better) The same as option 1, but to pluck the values, use array_map:
$numbers = array_map(function($details) {
return $details['Weight'];
}, $array);
Option 3.
Option 4. If you only need a min OR max, array_reduce() might be faster:
$min = array_reduce($array, function($min, $details) {
return min($min, $details['weight']);
}, PHP_INT_MAX);
This does more min()s, but they're very fast. The PHP_INT_MAX is to start with a high, and get lower and lower. You could do the same for $max, but you'd start at 0, or -PHP_INT_MAX.
foreach ($array as $k => $v) {
$tArray[$k] = $v['Weight'];
}
$min_value = min($tArray);
$max_value = max($tArray);
For the people using PHP 5.5+ this can be done a lot easier with array_column. Not need for those ugly array_maps anymore.
How to get a max value:
$highest_weight = max(array_column($details, 'Weight'));
How to get the min value
$lowest_weight = min(array_column($details, 'Weight'));
It is interesting to note that both the solutions above use extra storage in form of arrays (first one two of them and second one uses one array) and then you find min and max using "extra storage" array. While that may be acceptable in real programming world (who gives a two bit about "extra" storage?) it would have got you a "C" in programming 101.
The problem of finding min and max can easily be solved with just two extra memory slots
$first = intval($input[0]['Weight']);
$min = $first ;
$max = $first ;
foreach($input as $data) {
$weight = intval($data['Weight']);
if($weight <= $min ) {
$min = $weight ;
}
if($weight > $max ) {
$max = $weight ;
}
}
echo " min = $min and max = $max \n " ;
How about without using predefined functions like min or max ?
//find max
$arr = [4,5,6,1];
$val = $arr[0];
$n = count($arr);
for($i=0;$i<$n;$i++) {
if($val < $arr[$i]) {
$val = $arr[$i];
}
}
echo $val;
//find min
$arr = [4,5,6,1];
$val = $arr[0];
$n = count($arr);
for($i=0;$i<$n;$i++) {
if($val > $arr[$i]) {
$val = $arr[$i];
}
}
echo $val;
$num = array (0 => array ('id' => '20110209172713', 'Date' => '2011-02-09', 'Weight' => '200'),
1 => array ('id' => '20110209172747', 'Date' => '2011-02-09', 'Weight' => '180'),
2 => array ('id' => '20110209172827', 'Date' => '2011-02-09', 'Weight' => '175'),
3 => array ('id' => '20110211204433', 'Date' => '2011-02-11', 'Weight' => '195'));
foreach($num as $key => $val)
{
$weight[] = $val['Weight'];
}
echo max($weight);
echo min($weight);
<?php
$array = array (0 =>
array (
'id' => '20110209172713',
'Date' => '2011-02-09',
'Weight' => '200',
),
1 =>
array (
'id' => '20110209172747',
'Date' => '2011-02-09',
'Weight' => '180',
),
2 =>
array (
'id' => '20110209172827',
'Date' => '2011-02-09',
'Weight' => '175',
),
3 =>
array (
'id' => '20110211204433',
'Date' => '2011-02-11',
'Weight' => '195',
),
);
foreach ($array as $key => $value) {
$result[$key] = $value['Weight'];
}
$min = min($result);
$max = max($result);
echo " The array in Minnumum number :".$min."<br/>";
echo " The array in Maximum number :".$max."<br/>";
?>
$Location_Category_array = array(5,50,7,6,1,7,7,30,50,50,50,40,50,9,9,11,2,2,2,2,2,11,21,21,1,12,1,5);
asort($Location_Category_array);
$count=array_count_values($Location_Category_array);//Counts the values in the array, returns associatve array
print_r($count);
$maxsize = 0;
$maxvalue = 0;
foreach($count as $a=>$y){
echo "<br/>".$a."=".$y;
if($y>=$maxvalue){
$maxvalue = $y;
if($a>$maxsize){
$maxsize = $a;
}
}
}
echo "<br/>max = ".$maxsize;
print fast five maximum and minimum number from array without use of sorting array in php
:-
<?php
$array = explode(',',"78, 60, 62, 68, 71, 68, 73, 85, 66, 64, 76, 63, 81, 76, 73,
68, 72, 73, 75, 65, 74, 63, 67, 65, 64, 68, 73, 75, 79, 73");
$t=0;
$l=count($array);
foreach($array as $v)
{
$t += $v;
}
$avg= $t/$l;
echo "average Temperature is : ".$avg." ";
echo "<br>List of seven highest temperatsures :-";
$m[0]= max($array);
for($i=1; $i <7 ; $i++)
{
$m[$i]=max(array_diff($array,$m));
}
foreach ($m as $key => $value) {
echo " ".$value;
}
echo "<br> List of seven lowest temperatures : ";
$mi[0]= min($array);
for($i=1; $i <7 ; $i++)
{
$mi[$i]=min(array_diff($array,$mi));
}
foreach ($mi as $key => $value) {
echo " ".$value;
}
?>