Array = 1,5,2,3,7,1,2,4,8,4,0,9,11,15
x = 8
z = ?
How to find the max value that is lower than x, in my example it is 7 ( z )…
Couldn’t you sort the array so it is in numerical order, then find the number 8, and then choose the index right before that one? Since it is sorted numerically it should be the maximum.
After a numeric sort I think array_search would work well here.
Though IMHO if you’re going to do a “key - 1” it would be a good idea to use array_key_exists in case x is the lowest value.
You wouldn’t have to use array_key_exists, as if it is the very first value, it will have a key of 0 (assuming it isn’t using an associative array). Associative arrays don’t matter either, as when you sort (see the first note), it assigns a new key that starts at 0.
<?php
$numbers=array(1,5,2,3,7,1,2,4,8,4,0,9,11,15);
$sort = sort($numbers);
$arrlength=count($numbers);
for($x=0;$x<$arrlength;$x++)
{
echo $numbers[$x]. "\n";
}
$value = 8;
$key = array_search($value, $sort);
$keys = $key-1;
echo "max ",$key ."\n";
echo "avr ",$sort[$keys] ."\n";
?>
I made this script but it gives to me an error
Warning: array_search() expects parameter 2 to be array, boolean given
How to sort the array and use it as variable ?
Sort returns a bool. You want to use array_search($value, $numbers);
instead.
And change $sort[$keys]
to $numbers[$keys]
Also, I would change
$keys = $key-1;
to
$keys = ($key != 0) ? $key-1 : $key;
That way, if array_search returns the very first value in the array, it doesn’t blow up.
Yes sort returns a boolean
Return Values
Returns TRUE on success or FALSE on failure.
So unless you want to test for its success or failure for some reason once you do
sort($array)
$array will be sorted
EDIT
ninja’d
i need to use sorted array not the normal , in line 2 i tried o sort the array
Correct, sort($numbers)
is updating the $numbers
array to be sorted. It isn’t providing a new array, it is replacing itself.
Your for-loop should represent that, as the output should have been sequential
No need to sort. This is a job for array_reduce:
<?php
$numbers=array(1,5,2,3,7,1,2,4,8,4,0,9,11,15);
$x = 8;
$z = array_reduce($numbers,function($max,$number) use($x) {
// Ignore if greater
if ($number >= $x) return $max;
// First one less than x
if ($max === null) return $number;
// Replace if greater
return $max < $number ? $number : $max;
},null);
echo $z . "\n";
@ahundiak good job man that does the work also thanks to all other who replied. All the best
Just be sure that you can actually explain to your instructor what array_reduce does. Otherwise, it might be a bit embarrassing.
Looking at all these fancy codes I am wondering why a simple three-liner with a loop and a condition can’t do.
About a year ago I started to dabble in functional programming. So now whenever I get the urge to foreach over something, I try to see if one of the builtin array functions could be used instead. It’s what all the hip developers are doing.
I do think you need more than one comparison for maintainability. I’m sure I could combine the three statements into one but it would be messy. Unless you have a trick up your sleeve?
but you don’t need a function here. You need just a simple value out of array.
Regarding the number of conditions, I think that your second one is superfluous while to make something like (condition && condition)
from the rest doesn’t look that scaring to me.
I guess there’s always more than one way to do something.
This works, but I can’t say I feel all that good about it. Feels hacky.
$test_value = 8;
$test_array = [1,3,5,7,9,2,4,6,8];
function keep_less_thans(&$array_item, $array_key, $test_value){
if ($array_item >= $test_value){
$array_item = NULL;
}
}
array_walk($test_array, 'keep_less_thans', $test_value);
rsort($test_array);
print_r($test_array[0]);
This is how I would handle it:
$newNumbers=$numbers=array(1,5,2,3,7,1,2,4,8,4,0,9,11,15);// protect the original array by copying it
sort($newNumbers); // orders the array
$value = 8;
$key = array_search($value, $newNumbers); //searches for the upper limit
echo "max ",$newNumbers[($key>0) ? $key-1 : 0 ] ."\n";// return the key prior to the upper limit
Admittedly, this will error out if the exact limit is not present. For example if there is no 8 in the array.
array_filter could get rid of your keep_less_thans function:
$test_value = 8;
$test_array = [1,3,5,7,9,2,4,6,8];
$lessThans = array_filter($test_array,function($value) use($test_value) {
return $value < $test_value;
});
rsort($lessThans);
It is not a matter of many ways, it’s a matter of sanity. I’ve seen many times the PHP users’ enigmatic inclination to writing the longest and most entangled code they can muster.
Ok, a version from @ahundiak is good for educational purpose, but I’d hate if I had a colleague writing like this. May be it’s only me, but my job involves not only writing but also reading considerable amounts of code. And when I am reading the code, I want to be able to comprehend it’s purpose, but if it takes a couple lookups to PHP manual, it distracts me from the current task.
To me, a simple loop like this
$src = array(1,5,2,3,7,1,2,4,8,4,0,9,11,15);
$max = 8;
$res = null;
foreach ($src as $num) {
if ($num > $res && $num < $max) {
$res = $num;
}
}
is incomparable to any “other way to do it” presented here, as it’s both simpler and way more readable. It’s a code that even almost literally reads as the task description, if you read it aloud
for each array element, if it’s bigger than current value and at the same time it’s less than max value, then assign it to current value.
Try to read aloud one of any other codes here
not to mention that unlike other suggestions it involves only one single loop over the source array. Not I am going to say that it has any effect on performance but still…