add values to array by iterate one at a time - php

I am trying to get this function working by adding one point at at time, till there are no more.
What I am trying to do is, getting it to increment "Torsk" value by one, then go to the next, increment by one, and then so on an on, till all the points set in $prize have been distributed.
$prize = [
"Torsk" => 0,
"Rødspætte" => 0,
"Mørksej" => 0,
"Skrubbe" => 0,
"Lubbe/Lyssej" => 0,
"Ising" => 0,
"Lange" => 0,
"Makrel" => 0,
"Hornfisk" => 0,
"Pig-/Slet-hvar" => 0,
"Havkat" => 0,
"Laks/Havørred" => 0,
];
$points = 21;
for ($i = 0; $i < $points; ++$i) {
foreach ($prize as $key => $value) {
$prize[$key]++;
if (array_sum($prize) == $points) continue;
}
}
echo array_sum($prize);
echo "<br />";
print_r($prize);
When it is finished I expected the array to be like this:
$prize = [
"Torsk" => 2,
"Rødspætte" => 2,
"Mørksej" => 2,
"Skrubbe" => 2,
"Lubbe/Lyssej" => 2,
"Ising" => 2,
"Lange" => 2,
"Makrel" => 2,
"Hornfisk" => 2,
"Pig-/Slet-hvar" => 1,
"Havkat" => 1,
"Laks/Havørred" => 1,
];
But it is not, instead it has just added 21 to all of them.

you could use break 2; to break from outer loop when your condition is reached, like:
for ($i = 0; $i < count($prize); ++$i) {
foreach ($prize as $key => $value) {
$prize[$key]++;
if (array_sum($prize) == $points) {
break 2;
}
}
}

Try this code snippet:
$prize = [
"Torsk" => 0,
"Rødspætte" => 0,
"Mørksej" => 0,
"Skrubbe" => 0,
"Lubbe/Lyssej" => 0,
"Ising" => 0,
"Lange" => 0,
"Makrel" => 0,
"Hornfisk" => 0,
"Pig-/Slet-hvar" => 0,
"Havkat" => 0,
"Laks/Havørred" => 0,
];
$points = 21;
foreach ($prize as $key => $value) {
$prize[$key]++;
if (array_sum($prize) == $points) break;
}
if(array_sum($prize) < $points){
foreach ($prize as $key => $value) {
$prize[$key]++;
if (array_sum($prize) == $points) break;
}
}
echo array_sum($prize);
echo "<br />";
print_r($prize);

You should use break 2; instead of continue to break the two nested enclosing structures.
The following is an improved way to do the same task.
<?php
/**
* Disturbe values until the sum is equal to $points
* #param $prize array
* #param $points integer
* #return array|false
*/
function distribute_prize( $prize = array(), $points = 21 ){
$sum = array_sum( $prize );
if( $sum == $points ) return $points;
elseif( $sum > $points || $points < 0 ) return false;
while( true ){
foreach ($prize as $key => $value) {
$prize[$key]++;
if( array_sum( $prize ) == $points ) break 2;
}
}
return $prize;
}
// TEST
$prize = [
"Torsk" => 0,
"Rødspætte" => 0,
"Mørksej" => 0,
"Skrubbe" => 0,
"Lubbe/Lyssej" => 0,
"Ising" => 0,
"Lange" => 0,
"Makrel" => 0,
"Hornfisk" => 0,
"Pig-/Slet-hvar" => 0,
"Havkat" => 0,
"Laks/Havørred" => 0,
];
$points = 21;
print_r( distribute_prize( $prize, $points ) );

Related

Grouping of same values in an array

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

How to get next value from match value in foreach loop? [duplicate]

This question already has answers here:
Get next key in array
(4 answers)
Closed 21 days ago.
How to get next value from match value in loop? I need '1010-1040' key in array.
<?php
$arr = Array
(
'0900-0930' => 0,
'0935-1005' => 0,
'1010-1040' => 0,
'1045-1115' => 0
);
$matchVal = '0935-1005';
foreach ($arr as $key => $value) {
if($matchVal == $key){
echo $key.'<br />';
}
echo next($arr);
}
?>
Try This
$arr = Array
(
'0900-0930' => 0,
'0935-1005' => 0,
'1010-1040' => 0,
'1045-1115' => 0
);
$matchVal = '0935-1005';
$keys = array_keys($arr);
print $keys[array_search($matchVal,$keys)+1];
Output
1010-1040
<?php
$arr = Array
(
'0900-0930' => 0,
'0935-1005' => 0,
'1010-1040' => 0,
'1045-1115' => 0
);
$keys = array_keys($arr);
$matchVal = '0935-1005';
$matched = array_search($matchVal, $keys); // $key = 1;
$nextindex = $matched + 1;
$nextValue = $arr[$nextindex];
?>
Please try this.
<?php
$arr = Array
(
'0900-0930' => 0,
'0935-1005' => 0,
'1010-1040' => 0,
'1045-1115' => 0
);
$matchVal = '0935-1005';
foreach ($arr as $key => $value) {
if($matchVal == $key){
echo $key.'<br />';
}
next($arr);
echo key($arr)."<br/>;
}
?>

Adding numbers in a multidimensional array

Is there a faster way to add all the numbers in each segment of the multidimensional array rather than just doing it all manually? I was told before that a foreach loop could be used but I've hit a brick wall.
I'm trying to make it so it shows the total number of course enrollments in each campus and then the total number of students taking each course.
I feel like the answer is staring me in the face but I'm unsure.
<?
$campus = array();
$campus[1]['course1'] = 5; // <---- Number enrolled
$campus[1]['course2'] = 15;
$campus[1]['course3'] = 22;
$campus[1]['course4'] = 21;
$campus[1]['course5'] = 12;
$campus[1]['course6'] = 25;
$campus[1]['course7'] = 16;
$campus[1]['course8'] = 11;
$campus[1]['course9'] = 17;
$campus[1]['course10'] = 23;
$campus[2]['course1'] = 11;
$campus[2]['course2'] = 23;
$campus[2]['course3'] = 51;
$campus[2]['course4'] = 25;
$campus[2]['course5'] = 32;
$campus[2]['course6'] = 35;
$campus[2]['course7'] = 32;
$campus[2]['course8'] = 52;
$campus[2]['course9'] = 25;
$campus[2]['course10'] = 21;
$campus[3]['course1'] = 2;
$campus[3]['course2'] = 12;
$campus[3]['course3'] = 32;
$campus[3]['course4'] = 32;
$campus[3]['course5'] = 25;
$campus[3]['course6'] = 26;
$campus[3]['course7'] = 29;
$campus[3]['course8'] = 12;
$campus[3]['course9'] = 15;
$campus[3]['course10'] = 11;
echo "<pre>";
print_r($campus);
echo "<br/>";
foreach($campus as $key=>$value)
{
}
Use array_sum() to add the numbers in an array, and use array_map() to apply it to each element of the $campus array.
$total_by_campus = array_map('array_sum', $campus);
$courses = array();
foreach($campus as $key=>$value)
{
foreach($value as $course=>$num)
$courses[$course] += $num;
}
var_dump($courses);
Should do it.
You can use PHP's array_sum() function that will add up the values of the array you give it.
<?php
$sum = array_sum($campus[1]);
echo $sum;
$totcount = 0;
$count = array();
foreach($campus as $key=>$value)
{
foreach($value as $value1 => $value2)
{
$count[$value1]+=$value2;
$totcount++;
}
}
print_r($count);
echo "<br><br><br>". $totcount;
take a look:
$campus = array
(
'1' => array
(
'course1' => 5,
'course2' => 15,
'course3' => 22,
'course4' => 21,
'course5' => 12,
'course6' => 25,
'course7' => 16,
'course8' => 11,
'course9' => 17,
'course10' => 23,
),
'2' => array
(
'course1' => 11,
'course2' => 23,
'course3' => 51,
'course4' => 25,
'course5' => 32,
'course6' => 35,
'course7' => 32,
'course8' => 52,
'course9' => 25,
'course10' => 21,
),
'3' => array
(
'course1' => 2,
'course2' => 12,
'course3' => 32,
'course4' => 32,
'course5' => 25,
'course6' => 26,
'course7' => 29,
'course8' => 12,
'course9' => 15,
'course10' => 11,
),
);
foreach ($campus as $key0 => $value0)
{
// $key0 == (1, 2, 3)
// $value0 == array(course1 => 5, course2 => 15, course3 => 22, ...)
foreach ($value0 as $key1 => $value1)
{
// $key1 == (course1, course2, course3, ...)
// $value1 == (5, 15, 22, ...)
}
}
Sorry, but you post a question: "How to check an array's contents to see if they have any numbers?"
<?php
$cowboyfile = "COWBOY.TXT";
$data = array();
$data[] = "Colt Peacemaker, 12.20";
$data[] = "Holster, 2.00";
$data[] = "Levi Strauss Jeans, 1.35";
$data[] = "Saddle, 40.00";
$data[] = "Stetson, 10.00";
// Writing in the File
file_put_contents($cowboyfile, implode("\r\n", $data));
// Displaying all items above $10
$items = file($cowboyfile);
$item_filtred = array();
for ($i = 0; $i < count($items); $i++)
{
$item = $items[$i];
$item_price = substr($items[$i], strpos($item, ',') + 1);
if ($item_price >= 10)
{
$item_filtred[] = $item;
}
}
print_r($item_filtred);

How to get the minimum value from array row

I trying to get the minimum values from the any column contains "xx" in the column name.
Below is my code:
<?php
$array = array(
array(
'id' => 1,
'10xx' => 14,
'11xx' => 32,
'12xx' => 4
),
array(
'id' => 2,
'10xx' => 13,
'11xx' => 36,
'12xx' => 41
)
);
foreach($array as $item)
{
$lowestKey = '';
foreach($item as $key => $value)
{
if(strpos($key, 'xx') === 0)
{
if($lowestKey == '')
{
$lowestKey = $key;
}
else
{
if($value < $item[$lowestKey])
{
$lowestKey = $key;
}
}
}
}
echo 'lowest for id ' . $item['id'] . ': ' . $item[$lowestKey] . "\n";
}
?>
You have a function already for it:
http://php.net/manual/en/function.min.php
echo min(2, 3, 1, 6, 7); // 1
echo min(array(2, 4, 5)); // 2
echo min(0, 'hello'); // 0
echo min('hello', 0); // hello
echo min('hello', -1); // -1
Combine it with array_values if this fits better your needs.
function _getNumber($array) {
return $array['id'];
}
$numbers = array_map('_getNumber', $array);
OR
$numbers = array_map(function($array) {
return $array['id'];
}, $array);
echo $min = min($numbers);
echo $max = max($numbers);
function find_lowest($array){
$new_array = array();
foreach($array as $key => $val ){
if(is_array($val)){
$new_array[$key] = find_lowest($val);
}else{
$new_array[$key] = $val ;
}
}
return min($new_array);
}
$array = array( array( 'id' => 1,
'10xx' => 14,
'11xx' => 32,
'12xx' => 4
),
array(
'id' => 2,
'10xx' => 13,
'11xx' => 36,
'12xx' => 41
)
);
echo find_lowest($array);
Instead of looping again inside just use the min() function.
$lowest_keys = array();
foreach($array as $item)
{
unset( $item[ 'id' ] );
$lowest_keys[] = min( $item );
}
Iterate each row/subarray with a foreach() loop or array_walk().
Extract and display the id (first element) value with array_shift().
Call min() on the remaining values in the respective subarray to determine the lowest value.
No conditional expressions. No unnecessary variables. Clean, concise, and effective.
Code: (Demo)
$array = [
['id' => 1, '10xx' => 14, '11xx' => 32, '12xx' => 4],
['id' => 2, '10xx' => 13, '11xx' => 36, '12xx' => 41]
];
array_walk($array, function($row) {
echo array_shift($row) , " : " , min($row) , "\n";
});
Output:
1 : 4
2 : 13
$array = array(
array(
'id' => 14,
'10xx' => 14,
'11xx' => 32,
'12xx' => 4
),
array(
'id' => 2,
'10xx' => 13,
'11xx' => 36,
'12xx' => 41
)
);
$lowestKey = '';
foreach($array as $arra){
foreach ($arra as $key=>$value){
if ($key == 'id'){
if(($value < $lowestKey )||( $lowestKey== '')){
$lowestKey = $value;
}
}
}
}
echo $lowestKey;

Get min and max value in PHP Array

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;
}
?>

Categories