I have the following array:
Array ( [0] => 80 ) Array ( [0] => 20 ) Array ( [0] => 90 )
Code:
$percentage_query = $this->Common_model->getTableData('prop_payment_percentage', array('list_id' => $id));
$percentage_result = $percentage_query->result_array();
foreach ($percentage_result as $ptime) {
$percentage_start_date = $percentage_query->row()->start_date;
$percentage_end_date = $percentage_query->row()->end_date;
$percentage_percentage = $percentage_query->row()->percentage;
//Days between start date and end date -> seasonal price
$start_time = $ptime['start_date'];
$end_time = $ptime['end_date'];
$hightest_percentage = $ptime['percentage']; // this is the array 802090
//help me echo 90
}
How should i return the Value 90? As It is the highest number which i would like to return into a $variable
Unless the array is sorted, that's the best you're going to get. If it is sorted, just take the first and last elements.
Of course, if it's not sorted, then sorting first and grabbing the first and last is guaranteed to be less efficient than just looping through once. Even the best sorting algorithms have to look at each element more than once (an average of O(log N) times for each element. That's O(N*Log N) total. A simple scan once through is only O(N).
If you are wanting quick access to the largest element in a data structure, take a look at heaps for an efficient way to keep objects in some sort of order.
sort() - sort arrays in ascending order
rsort() - sort arrays in descending order
asort() - sort associative arrays in ascending order, according to the value
ksort() - sort associative arrays in ascending order, according to the key
arsort() - sort associative arrays in descending order, according to the value
krsort() - sort associative arrays in descending order, according to the key
if we use ascending order then to access last element we have to count array size and arr[last_position] gives highest order
But by sorting array in descending order there is no need to count array size. Just access first number and you will get highest number
if you have an array containing your arrays, you can do it like this:
$masterArray = array(
array(80),
array(20),
array(90),
);
$highestValue = 0;
foreach($masterArray as $arr){
$highestValue = $arr[0] > $highestValue ? $arr[0] : $highestValue;
}
echo $highestValue; //echo 90;
Here is the example If you have 3 array or variables.
$a1 = Array ( "0" => 80 );
$a2 = Array ( "0" => 20 );
$a3 = Array ( "0" => 90 );
$a4 = array_merge($a1,$a2);
$a5 = array_merge($a4,$a3);
echo '<pre>';
print_r(max($a5));
You don't need to loop. Merge the three arrays and then use max();
$array = array_merge(array(80),array(20),array(20));
$max = max($array);
<?
$a=array(0 => 1300 );
$b=array(0 => 500 );
$c=array(0 => 1220 );
$MaxValue=0;
if($a[0]>$b[0])
{
$MaxValue=$a[0];
if($b[0]>$MaxValue)
{
$MaxValue=$b[0];
}
else
{
if($c[0]>$MaxValue)
{$MaxValue=$c[0];}
}
}
else
{
if($b[0]>$c[0])
{
$MaxValue=$b[0];
}
else
{
$MaxValue=$c[0];
}
}
echo $MaxValue;
?>
The easiest way would be to use the standard code function from php:
$array = array(0 => 80, 1 => 20, 2 => 90);
$variable = max($array);
See also the documentation at http://php.net/manual/en/function.max.php
update: this function takes more than just an array of integers. All these are valid and return 3 as expected:
$a1 = array(1);
$a2 = array(2);
$a3 = array(3);
$i1 = 1;
$i2 = 2;
$i3 = 3;
$arr1 = array($a1, $a2, $a3);
$arr2 = array($i1, $i2, $i3);
echo max($a1, $a2, $a3), "\n"; // 3
echo max($i1, $i2, $i3), "\n"; // 3
echo max($arr1), "\n"; // 3
echo max($arr2), "\n"; // 3
It does not matter what keys are used in the arrays.
update 2: if you really need to work from the value 802090 and you can be sure that the values are always 2-digit percentages, you could also use the str_split function (and then again the max function):
$hightest_percentage = 802090;
$hpr = str_split($hightest_percentage, 2); // array ( 80, 20, 90 );
print_r(max($hpr)); // 90
Related
I have been trying to match a string with the values in an array and output the array strings starting from the string with the highest character match count. for example:
$array = array(
'mike'=>'book21',
'ben'=>'buzz',
'jack'=>'airdrone',
'july'=>'march',
'fred'=>'blend45'
);
$string = 'blenmaio2';
As you can see, 'blend45', has the highest matched characters, with a total of 4 matched characters. I want to be able to output them starting from the first four highest match count, here is an example of the output i want:
blend45
book21
march
buzz
This is my first time trying to help someone, so hopefully this does the trick. I know you can probably simplify the code a little, but this is what I have.
<?php
$array = array(
'mike'=>'book21',
'ben'=>'buzz',
'jack'=>'airdrone',
'july'=>'march',
'fred'=>'blend45'
);
$string = 'blenmaio2';
$sort_array=array(); //Empty array
foreach ($array as $key => $value){
$num = similar_text($value,$string); //Using similar text to compar the strings.
$sort_array[$value] = $num; //Adding the compared number value and sring value to array.
}
arsort($sort_array, SORT_REGULAR);//Sorting the array by the larges number.
print_r ($sort_array);
//creating another foreach statement to get the output you wanted.
$count = 0;
foreach($sort_array as $key => $value){
$count++;
echo $count.". ".$key."\n";
};
?>
Results:
Array
(
[blend45] => 4
[book21] => 3
[airdrone] => 3
[march] => 2
[buzz] => 1
)
1. blend45
2. book21
3. airdrone
4. march
5. buzz
I think the levenshtein() function would be the most appropriate method to achieve your goal:
$array = array(
'mike'=>'book21',
'ben'=>'buzz',
'jack'=>'airdrone',
'july'=>'march',
'fred'=>'blend45'
);
$string = 'blenmaio2';
uasort($array, function($a, $b) use ($string) {
$aDistance = levenshtein($string, $a);
$bDistance = levenshtein($string, $b);
return ($aDistance < $bDistance) ? -1 : 1;
});
print_r($array);
// Output:
// Array
// (
// [fred] => blend45
// [july] => march
// [mike] => book21
// [ben] => buzz
// [jack] => airdrone
// )
http://php.net/levenshtein
Update Use uasort() instead of usort() to preserve the array keys.
I just noticed that my answer compares the similarity, but doesn't meet the highest character count match, so sorry for that :)
Here you are my answer. It is a bit different, because I'm using levenshtein function for finding nearest between two words.
I'm using uasort to reorder the array in way you liked.
Of course you can replace the algorithm for nearest by your function.
<?php
$array = array(
'mike'=>'book21',
'ben'=>'buzz',
'jack'=>'airdrone',
'july'=>'march',
'fred'=>'blend45'
);
$string = 'blenmaio2';
function cmp($a,$b){
global $string;
$aa=levenshtein($a, $string);
$bb=levenshtein($b, $string);
if($aa>$bb)
return 1;
elseif($bb>$aa)
return -1;
else return 0;
}
uasort($array,cmp);
?>
<pre><?= print_r($array); ?></pre>
I am trying to make a function where I get data from specific positions in an array, and then add(plus) the results together. Something like this:
$specificPositionsInArray = "1,4,12,27,40,42,48,49,52,53,56,58";
$dataArray = "1,2,3,4,5,6,7,8"; // More than hundred values.
myfunction($specificPositionsInArray) {
// Find position in array, based on $specificPositionsInArray and then
// plus the value with the previous value
// that is found in the $specificPositionsInArray.
// Something like:
$value = $value + $newValue;
return $value;
}
So if $specificPositionsInArray was 1,3,5
The $value that should be returned would be: 9 (1+3+5) (based on the $dataArray).
Maybe there is another way to do it, like without the function.
Here's a functional approach:
$specificPositionsInArray = array(1,3,7,6);
$dataArray = array(1,2,3,4,5,6,7,8);
function totalFromArrays($specificPositionsInArray, $dataArray) {
foreach ($specificPositionsInArray as $s){
$total += $dataArray[$s];
}
return $total;
}
$total = totalFromArrays($specificPositionsInArray, $dataArray);
echo $total;
You should look into arrays and how to handle them, you could have found the solution pretty easily. http://www.php.net/manual/en/book.array.php
//$specificPositionsInArray = array(1,4,12,27,40,42,48,49,52,53,56,58);
$specificPositionsInArray = array(1,3,5);
$dataArray = array(1,2,3,4,5,6,7,8);
$total=0;
foreach($specificPositionsInArray as $k => $v){
$total += $dataArray[$v-1];
}
echo $total;
The weird part about this is the $v-1 but because of how you want to handle the addition of the items, and an array starts with element 0, you have to subtract 1 to get to the right value.
So you want to do something like this:
$dataArray = array(1,2,3,4,5...); // 100+ values, not necessarily all integers or in ascending order
$specificPositions = array(1, 3, 5);
function addSpecificPositions($data, $positions) {
$sum = 0;
foreach($positions as $p)
$sum += $data[$p];
return $sum;
}
If you really want to keep your list of values in a string (like you have it in your example), you'll have to do an explode first to get them in array form.
Since it looks like your array is using numeric values for the keys this should be fairly easy to calculate. I refactored your code a little to make it easier to read:
$specificPositionsInArray = array(1,4,6,7);
By default PHP will assign numeric keys to each value in your array, so it will look like this to the interpreter.
array(
[0] => 1,
[1] => 4,
[2] => 6,
[3] => 7
)
This is the same for all arrays unless you specify a numeric or mixed key. Since the data array seems to just be values, too, and no keys are specified, you can simply target them with the key that they will be associated with. Say I use your array example:
$dataArray = array(1,2,3,4,5,6,7,8);
This will look like this to the parser:
array(
[0] => 1,
[1] => 2,
[2] => 3,
[3] => 4,
[4] => 5,
[5] => 6,
[6] => 7,
[7] => 8
)
If you wanted to select the number 6 from this array, you actually need to use $dataArray[5] since array keys start at zero. So for your function you would do this:
$specificPositionsInArray = array(1,4,6,7);
$dataArray = array(1,2,3,4,5,6,7,8);
calculate_array($specificPositionsInArray, $dataArray); // Returns 18
function calculate_array($keys, $data){
$final_value = 0; // Set final value to 0 to start
// Loop through values
foreach($keys as $key){
// Add the keys to our starting value
$final_value += $data[$key-1]; // minus 1 from key so that key position is human readable
}
// return the sum of the values
return $final_value;
}
I have a multidimensional array:
$arr = array(
array('lions', 'tigers', 'bears'), // count = 3
array('dogs', 'cats'), // count = 2
array('horses', 'pigs', 'cattle', 'sheep', 'chickens') // count = 5
);
I want to return the array with the lowest count (I don't need to know the count, just need the array that HAS the lowest count). In this case, array('dogs', 'cats')
Right now I have:
$lowest = null;
foreach($nodePath as $arr)
{
$lowest = count($arr) < count($lowest) || $lowest == null ? $arr : $lowest;
}
This works but I'm wondering if I missed a more contained solution, perhaps using array_map, array_walk or a similar function.
Use array_map() with count as a callback to get the number of elements in each array, min() to get the smallest value. Then, to get the key of the smallest array - use array_flip() to flip the arrays keys and values, and access the $minth index. Now you can use the key to get the array you need:
$counts = array_map('count', $arr);
$min = min($counts);
$key = array_flip($counts)[$min];
$smallest_arr = $arr[$key];
Demo
Map your array to another array with counts of each child array. Get the key of the minimum value in this new array. Smallest array has the key of the minimum value:
$count = array_map('count', $arr);
$min = array_keys($count , min($count))[0];
var_dump($arr[$min]); // Array ( [0] => dogs [1] => cats )
Eval.in
I have 2 arrays with for example 1000 key's each, one holds a temperature value and the other the hour.
Example array temp:
[0] = 3.1
[1] = 4.3
[2] = 4.1
[3] = 5.1
[4] = 4.1
Example hour array:
[0] = 0
[1] = 1
[2] = 2
[3] = 3
[4] = 3
The problem with this is that when i combine these to arrays and plot this in for example pchart i have too many values on the X and it gets cluttered.
So what i need to to remove the duplicate hours and replace then with "NULL", so that the unneeded hours are not plotted on the x axis.
I want to keep the first hour in the array, the second to the end of the duplicates can be set to "NULL"
The hour output array should be:
[0] = 0
[1] = 1
[2] = 2
[3] = 3
[4] = NULL
etc.
Sounds like a job for array_unique().
array array_unique ( array $array [, int $sort_flags = SORT_STRING ] )
Takes an input array and returns a new array without duplicate values.
Note that keys are preserved. array_unique() sorts the values treated
as string at first, then will keep the first key encountered for every
value, and ignore all following keys. It does not mean that the key of
the first related value from the unsorted array will be kept.
Note: Two elements are considered equal if and only if (string) $elem1
=== (string) $elem2. In words: when the string representation is the same. The first element will be used.
If you require the array keys to persist, you can try something with array_map().
<?php
//Variable initialization
$array = array(
0 => 0,
1 => 1,
2 => 2,
3 => 3,
4 => 3
);
$temp = array();
$array = array_map(function($element) use (&$temp) {
if (!in_array($element, $temp)) {
$temp[] = $element;
return $element;
}
return null;
}, $array);
print_r($array);
Your array is sorted, so... how about this?
$hours = array(0,1,2,3,3,4,4,5);
$prev = -1;
foreach ($hours as &$hour) {
if ($prev === $hour) {
$hour = NULL;
}
else {
$prev = $hour;
}
}
unset($hour);
print_r($hours); // 0,1,2,3,NULL,4,NULL,5...
If you're using php 5.3:
$a = array(0,1,2,3,4,4,5);
array_walk($a, function(&$item) {
static $encountered = array();
if(in_array($item, $encountered)) {
$item = null;
return;
}
$encountered[] = $item;
});
var_dump($a);
Will preserve the number of keys. Array_walk calls a user function for every key. static makes it so that the $encountered array in the scope of the function stays between executions.
If you want to remove the duplicates entirely you can use array_unique()
but it wont set them to NULL.
Maybe this trick does it:
$simplified = array_combine($hours, $temperatures);
$hours = array_keys($simplified);
$temperatures = array_values($simplified);
This won't set things to NULL but to completely remove them which I think is what you're looking for. Otherwise this should do it:
foreach(array_slice(array_reverse(array_keys($hours)), 0, -1) as $i)
($hours[$i] === $hours[$i-1]) && $hours[$i] = NULL;
Demo
Is it possible to easily 'rotate' an array in PHP?
Like this:
1, 2, 3, 4 -> 2, 3 ,4 ,1
Is there some kind of built-in PHP function for this?
$numbers = array(1,2,3,4);
array_push($numbers, array_shift($numbers));
print_r($numbers);
Output
Array
(
[0] => 2
[1] => 3
[2] => 4
[3] => 1
)
Most of the current answers are correct, but only if you don't care about your indices:
$arr = array('foo' => 'bar', 'baz' => 'qux', 'wibble' => 'wobble');
array_push($arr, array_shift($arr));
print_r($arr);
Output:
Array
(
[baz] => qux
[wibble] => wobble
[0] => bar
)
To preserve your indices you can do something like:
$arr = array('foo' => 'bar', 'baz' => 'qux', 'wibble' => 'wobble');
$keys = array_keys($arr);
$val = $arr[$keys[0]];
unset($arr[$keys[0]]);
$arr[$keys[0]] = $val;
print_r($arr);
Output:
Array
(
[baz] => qux
[wibble] => wobble
[foo] => bar
)
Perhaps someone can do the rotation more succinctly than my four-line method, but this works anyway.
It's very simple and could be done in many ways. Example:
$array = array( 'a', 'b', 'c' );
$array[] = array_shift( $array );
Looping through the array, and shift-ing and push-ing, may be a common way to rotate an array, however it can often mess up your keys. A more robust method is using a combination of array_merge and array_splice.
/**
* Rotates an array.
*
* Numerical indexes will be renumbered automatically.
* Associations will be kept for keys which are strings.
*
* Rotations will always occur similar to shift and push,
* where the number of items denoted by the distance are
* removed from the start of the array and are appended.
*
* Negative distances work in reverse, and are similar to
* pop and unshift instead.
*
* Distance magnitudes greater than the length of the array
* can be interpreted as rotating an array more than a full
* rotation. This will be reduced to calculate the remaining
* rotation after all full rotations.
*
* #param array $array The original array to rotate.
* Passing a reference may cause the original array to be truncated.
* #param int $distance The number of elements to move to the end.
* Distance is automatically interpreted as an integer.
* #return array The modified array.
*/
function array_rotate($array, $distance = 1) {
settype($array, 'array');
$distance %= count($array);
return array_merge(
array_splice($array, $distance), // Last elements - moved to the start
$array // First elements - appended to the end
);
}
// Example rotating an array 180°.
$rotated_180 = array_rotate($array, count($array) / 2);
Alternatively, if you also find the need to rotate keys so that they match with different values, you can combine array_keys, array_combine, array_rotate, and array_values.
/**
* Rotates the keys of an array while keeping values in the same order.
*
* #see array_rotate(); for function arguments and output.
*/
function array_rotate_key($array, $distance = 1) {
$keys = array_keys((array)$array);
return array_combine(
array_rotate($keys, $distance), // Rotated keys
array_values((array)$array) // Values
);
}
Or alternatively rotating the values while keeping the keys in the same order (equivalent to calling the negative distance on the matching array_rotate_key function call).
/**
* Rotates the values of an array while keeping keys in the same order.
*
* #see array_rotate(); for function arguments and output.
*/
function array_rotate_value($array, $distance = 1) {
$values = array_values((array)$array);
return array_combine(
array_keys((array)$array), // Keys
array_rotate($values, $distance) // Rotated values
);
}
And finally, if you want to prevent renumbering of numerical indexes.
/**
* Rotates an array while keeping all key and value association.
*
* #see array_rotate(); for function arguments and output.
*/
function array_rotate_assoc($array, $distance = 1) {
$keys = array_keys((array)$array);
$values = array_values((array)$array);
return array_combine(
array_rotate($keys, $distance), // Rotated keys
array_rotate($values, $distance) // Rotated values
);
}
It could be beneficial to perform some benchmark tests, however, I expect that a small handful of rotations per request wouldn't affect performance noticeably regardless of which method is used.
It should also be possible to rotate an array by using a custom sorting function, but it would most likely be overly complicated. i.e. usort.
A method to maintain keys and rotate. using the same concept as array_push(array, array_shift(array)), instead we will use array_merge of 2 array_slices
$x = array("a" => 1, "b" => 2, "c" => 3, 'd' => 4);
To move the First element to the end
array_merge(array_slice($x, 1, NULL, true), array_slice($x, 0, 1, true)
//'b'=>2, 'c'=>3, 'd'=>4, 'a'=>1
To move the last element to the front
array_merge(array_slice($x, count($x) -1, 1, true), array_slice($x, 0,
//'d'=>4, 'a'=>1, 'b'=>2, 'c'=>3
you can use this function:
function arr_rotate(&$array,$rotate_count) {
for ($i = 0; $i < $rotate_count; $i++) {
array_push($array, array_shift($array));
}
}
usage:
$xarr = array('1','2','3','4','5');
arr_rotate($xarr, 2);
print_r($xarr);
result:
Array ( [0] => 3 [1] => 4 [2] => 5 [3] => 1 [4] => 2 )
There's a task about array rotation on Hackerrank: https://www.hackerrank.com/challenges/array-left-rotation/problem.
And proposed solution with array_push and array_shift will work for all test cases except the last one, which fails due to timeout. So, array_push and array_shift will give you not the fastest solution.
Here's the faster approach:
function leftRotation(array $array, $n) {
for ($i = 0; $i < $n; $i++) {
$value = array[$i]; unset(array[$i]); array[] = $value;
}
return array;
}
Use array_shift and array_push.
$daynamesArray = array("Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday");
array_push($daynamesArray, array_shift($daynamesArray)); //shift by one
array_push($daynamesArray, array_shift($daynamesArray)); //shift by two
print_r($daynamesArray);
The output starts at "Wednesday":
Array ( [0] => Wednesday [1] => Thursday [2] => Friday [3] => Saturday [4] => Sunday [5] => Monday [6] => Tuesday
Yes it is, here is a function I did myself, where $A is the array and $K the number of times you want to rotate the array:
function solution($A, $K) {
for($i = 0; $i < $K; $i++): //we cycle $K
$arrayTemp = $A;
for($j = 0; $j < count($arrayTemp); $j++): // we cycle the array
if($j == count($arrayTemp) - 1) $A[0] = $arrayTemp[$j]; // we check for the last position
else $A[$j + 1] = $arrayTemp[$j]; // all but last position
endfor;
endfor;
return $A;
}
The logic is to swap the elements. Algorithm may look like -
for i = 0 to arrayLength - 1
swap( array[i], array[i+1] ) // Now array[i] has array[i+1] value and
// array[i+1] has array[i] value.
No. Check the documentation for array_shift and its related functions for some tools you can use to write one. There might even be an array_rotate function implemented in the comments of that page.
It's also worth reading through the array functions listed on the left-hand sidebar to get a full understanding of what array functions are available in PHP.
Here's a function to rotate an array (zero-indexed array) to any position you want:
function rotateArray($inputArray, $rotateIndex) {
if(isset($inputArray[$rotateIndex])) {
$startSlice = array_slice($inputArray, 0, $rotateIndex);
$endSlice = array_slice($inputArray, $rotateIndex);
return array_merge($endSlice, $startSlice);
}
return $inputArray;
}
$testArray = [1,2,3,4,5,6];
$testRotates = [3, 5, 0, 101, -5];
foreach($testRotates as $rotateIndex) {
print_r(rotateArray($testArray, $rotateIndex));
}
Not too dissimilar to the first snippet in ShaunCockerill's answer, I also endorse not making iterated functions calls to perform the rotation. In fact, I'll recommend using early returns to optimize performance and reduce the total number of function calls needed.
The following snippet is the "move left" version of the "move right" version that I posted here. In my demo, there is a single, static input array and the foreach() loop merely changes the desired amount of rotation (0 to 9).
Code: (Demo)
function shiftPop(array $indexedArray, int $shiftPopsCount): array
{
$count = count($indexedArray);
if ($count < 2) {
return $indexedArray;
}
$remainder = $shiftPopsCount % $count;
if (!$remainder) {
return $indexedArray;
}
return array_merge(
array_splice($indexedArray, $remainder),
$indexedArray
);
}
$array = [1, 2, 3, 4];
foreach (range(0, 9) as $moves) {
var_export(shiftPop($array, $moves));
echo "\n---\n";
}
The first if block in my snippet is not engaged by my demo because my array always has 4 elements. The second if block is engaged, when $moves is 0, 4, and 8 -- in these cases, the input is identical to the desired output, so calling array_merge() and array_splice() is pointless.