I have an array with integers of values from 0 to 100. I wish to remove integers that are less than number X and keep the ones that are equal or greater than number X.
A little ugly using the clunky create_function, but straight forward:
$filtered = array_filter($array, create_function('$x', 'return $x >= $y;'));
For PHP >= 5.3:
$filtered = array_filter($array, function ($x) { return $x >= $y; });
Set $y to whatever you want.
Smarter than generating an array that is too big then cutting it down to size, I recommend only generating exactly what you want from the very start.
range() will do this job for you without the bother of an anonymous function call iterating a condition.
Code: (Demo)
$rand=rand(0,100); // This is your X randomly generated
echo $rand,"\n";
$array=range($rand,100); // generate an array with elements from X to 100 (inclusive)
var_export($array);
Potential Output:
98
array (
0 => 98,
1 => 99,
2 => 100,
)
Alternatively, if you truly, truly want to modify the input array that you have already generated, then assuming you have an indexed array you can use array_slice() to remove elements using X to target the starting offset and optionally preserve the indexes/keys.
Code: (Demo)
$array=range(0,100);
$rand=rand(0,100); // This is your X randomly generated
echo $rand,"\n";
var_export(array_slice($array,$rand)); // reindex the output array
echo "\n";
var_export(array_slice($array,$rand,NULL,true)); // preserve original indexes
Potential Output:
95
array (
0 => 95,
1 => 96,
2 => 97,
3 => 98,
4 => 99,
5 => 100,
)
array (
95 => 95,
96 => 96,
97 => 97,
98 => 98,
99 => 99,
100 => 100,
)
Related
How would someone merge 2 arrays where $_array_1 is scattered but $_array_2 maintains its original order globally?
I have 2 arrays
$_array_1 = array( a, b, c );
$_array_2 = array( 1, 2, 3, 4, 5, 6 );
$_merged_array = array( c, 1, a, 2, 3, 4, 5, b, 6 );
I know this must be possible but don't have a clue where to start. What is the most efficient method and cleanest?
My interpretation of your post is: Insert every value of array 1 on a random position in array 2. This can be achieved with the following code:
$_array_1 = array( 290, 188, 519 );
$_array_2 = array( 213, 702, 231, 173, 632, 711 );
foreach($_array_1 as $val) {
array_splice($_array_2, rand(0, count($_array_2)), 0, $val);
}
print_r($_array_2); // For example: Array ( [0] => 519 [1] => 213 [2] => 290 [3] => 702 [4] => 231 [5] => 173 [6] => 632 [7] => 188 [8] => 711 )
I don't see how the end result makes sense, but here's what you can do:
Copy the second array in the merged array,
Insert the values in the first array at random positions in the merged array using $insert_position = mt_rand(0, count($merged_array)).
Note that it's not an error that I didn't do count($merged_array) - 1, because we also want the numbers to be randomly added at the end of the array.
This is taken from the php.net manual for json_decode(), Example 4, 5th line from the bottom there:
foreach (range(4, 3, -1) as $depth)
I am not sure what is the purpose of that -1 there. I tried range(4, 3, 1) and range (4, 3, -1) and it gives the same results. The 1 in the first example is the default so it could be range(4, 3). I was only trying it with something like print_r(range(4, 3, -1); so the example on the php.net may be a different thing. I was looking on the Net and there is no info about it, or not right away.
It will actually ignore the sign of the $step argument, and determine whether to increment or decrement based purely on whether $start > $end or $end > $start. For example:
<?php print_r( range( 20, 11, 3 ) ); ?>
Array
(
[0] => 20
[1] => 17
[2] => 14
[3] => 11
)
<?php print_r( range( 11, 20, -3 ) ); ?>
Array
(
[0] => 11
[1] => 14
[2] => 17
[3] => 20
)
Step is automatically cast to a positive number (yes, the manual is incorrect here)
So all of these will work:
var_dump(
range(1, 5, 1), // positive integer
range(1, 5, -1), // negative integer
range(1, 5, 2),
range(1, 5, .5), // positive fractional number
range(1, 5, "-0.1") // negative fractional number passed as string
);
Also, if you use a float value as $step, all the values will be float too, even if they are whole numbers.
In PHP I have an Array like this:
$BulkArray[$i]
This Array is feed with plenty of Numbers (e.g. 1 => 100, 2 => 300, 3 => 100, and so on).
Now I want to find within the whole range of numbers, the greatest succession of a number equal or less than 500. I want to write the number of succession.
for example I have the array
1 => 100, 2 => 300, 3 => 100,
4 => 50, 5 => 50, 6 => 50, 7 => 50, 8 => 50,
9 => 500, 10 => 200, 11 => 100
as you can see, number 1,2 & 3 are together 500. So this is the first succession.
2,3,4,5 are also 500 together. (This succession(4) is bigger than the first succession(3))
And so on,then you will get the highest succession: 3,4,5,6,7,8 (succession with 6 numbers) which is 350 (but lower than 500m, as we searched for it)
Now, how can I write with the Array:
$BulkArray[$i], that the highest succession is 6 ?
Because 6 is the highest succession found in the whole array for 500!
(It's for categorizing specific Carparts)
The answer of User "fas M" here again, with little improvement:
<?php //lets call your $BulkArray = $values;
$values=array( 1 => 100, 2 => 300, 3 => 100,
4 => 50, 5 => 50, 6 => 50, 7 => 50, 8 => 50,
9 => 500, 10 => 200, 11 => 100 );
$sum=0; // to sum up until 500
$Vals500=array(); // array to store index with <= 500
$i=0; // index for new aaray that will store keys that made up <= 500
$key1=1; //value to iterate the array defined above
for($key=1; $key <= count($values); $key++){
$sum = $sum + $values[$key]; // get sum of values
if($sum <= 500){ $Vals500[$i][]=$key; } //append all key of sum ==500
if($sum >= 500) { $i++; $key=$key1++; $sum=0; } //check sum then reintialize
//added bigger equal
}
echo count(max($Vals500)); // read out the biggest succession
?>
Thanks again to fas M !
Click Here or here you can see somehing
<?php //lets call your $BulkArray = $values;
$values=array( 1 => 100, 2 => 300, 3 => 100,
4 => 50, 5 => 50, 6 => 50, 7 => 50, 8 => 50,
9 => 500, 10 => 200, 11 => 100 );
$sum=0; // to sum up until 500
$Vals500=array(); // array to store index with <= 500
$i=0; // index for new aaray that will store keys that made up <= 500
$key1=1; //value to iterate the array defined above
//print_r($values); echo '<br/>';
for($key=1; $key <= count($values); $key++){
$sum = $sum + $values[$key]; // get sum of values
if($sum <= 500){ $Vals500[$i][]=$key; } //append all key of sum ==500
if($sum == 500) { $i++; $key=$key1++; $sum=0; } //check sum then reinitialize values
}
foreach($Vals500 as $val){} //search for second array with many indeces in $Vals500. NB: i fail this place
echo print_r($Vals500);
print 'the highest succession found is '; print_r($Vals500[2]); //
?>
$arr =array(
28 => 23,
26 => 23,
15 => 12,
29 => 12,
1 => 12,
16 => 15,
30 => 15,
11 => 12,
8 => 23,
33 => 23
);
how to sort like this :
8 => 23
26 => 23
28 => 23
33 => 23
16 => 15
30 => 15
1 => 12
11 => 12
15 => 12
29 => 12
Use uksort, but make the array available to the comparison function for the secondary comparison by value. Making it a global variable would be the quickest + dirtiest way.
You could use uksort() which enables the custom callback to take a look at both the keys and, indirectly, their associated values. Then it's a simple matter of deciding which comparisons to make and returning the appropriate greater-than-less-then-or-zero value to influence the sort order.
Here's an example using a closure around a temporary variable (see Jacob's comment) which should hopefully make sense.
$temp = $arr;
uksort($arr, function ($a,$b) use ($temp) {
// Same values, sort by key ascending
if ($temp[$a] === $temp[$b]) {
return $a - $b;
}
// Different values, sort by value descending
return $temp[$b] - $temp[$a];
});
unset($temp);
print_r($arr);
Its quite easy. First use ksort and then use asort for the new sorted array. You will find your result.
I have an example array:
$a = array(
5 => 35,
16 => 22,
7 => 22,
3 => 22,
11 => 22,
9 => 27,
);
and I want to sort it by values and remember its keys.
Result that I expected was:
$a = array(
16 => 22,
7 => 22,
3 => 22,
11 => 22,
9 => 27,
5 => 35,
);
So my first thought was: asort !
Ok, I did
asort($a);
But no - it didn't just move 5 => 35 to the end of the array.
It changed my array to:
$a = array(
11 => 22,
3 => 22,
7 => 22,
16 => 22,
9 => 27,
5 => 35
);
You see ? Keys with the same value are reverse sorted. Why ?
You can't expect a certain sorting order for equal values. From the PHP manual on Sorting Arrays:
If any of these sort functions evaluates two members as equal then the order is undefined (the sorting is not stable).
"Why" is another question.
But it actually did what you were asking for, didn't it?
Key order weren't determined.
If you want certain order of keys, you should state it in the exercise conditions
http://en.wikipedia.org/wiki/Sorting_algorithm#Stability
in short, making sure that the order of the already sorted keys remains the same would cost computation time (and whoever designed the function at PHP decided it wasn't worth it)
Depending on the sort algorithm, it probably started sorting in another manner than just detecting that it should only move that single pair. But it ended up with a validly sorted array maintaining keys/values. they only look swapped cuz you have 4 keys with values of 22.