PHP sorting arrays numerically by key value - php

I'm trying to sort several arrays in numerical order based on the value in their first key:
$array1[0] = '1';
$array1[1] = 'content';
$array1[2] = 'more content';
$array3[0] = '3';
$array3[1] = 'content';
$array3[2] = 'more content';
$array4[0] = '4';
$array4[1] = 'content';
$array4[2] = 'more content';
$array2[0] = '2';
$array2[1] = 'content';
$array2[2] = 'more content';
$arrays = array($array1, $array3, $array4, $array2);
foreach ($arrays as $array) {
echo $array[0] . ' ' . $array[1] . ' ' . $array[2] . '<br>';
}
That outputs the arrays in a '1, 3, 4, 2' sequence, I need them to be output thusly: '1, 2, 3, 4'. Not sure how or even if to use the ksort/asort/array_multisort functions here.

You will need a custom comparison function that you then can use with usort or uasort:
function cmp($a, $b) {
return intval($a[0]) - intval($b[0]);
}
usort($arrays, 'cmp');
As of PHP 5.3 you could also use an anonymous function for the comparison function:
usort($arrays, function($a, $b) { return intval($a[0]) - intval($b[0]); });
You could also use array_multisort, create an array of the keys that are to be sorted first and use it to sort the array items itself:
$keys = array();
foreach ($arrays as $array) $keys[] = intval($array[0]);
array_multisort($keys, $arrays);
Doing this prevents calling the comparing function for each pair of values that is compared as only the key values are compared.

Using usort you can specify your own sorting criteria on an array. This is an idea of how you could achieve what you ask for
function cmp($a, $b)
{
if ($a == $b) {
return 0;
}
return (intval($a[0]) < intval($b[0])) ? -1 : 1;
}
usort($arrays, "cmp");

Related

How to get array min value

I have multidimensional array and me need to get a minimum value.
Array may be [65,4,4,511,5,[[54,54[.[.[..].].]] and so on.
example code
<?php
$arr = [5, 1 , 2, 3, [1,5,59,47,58,[0,12,562]]];
function NumMin($arr)
{
$num = '';
foreach ($arr as $item => $i) {
if(is_array($i)){
NumMin($i);
}
else{
$num .= $i.',';
}
}
$num .= $num;
return $num;
}
$g = NumMin($arr);
var_dump($g);
I need to get 0
You can use array_walk_recursive() function to flatten a given array (makes it one-dimensional).
And use simply min() function for getting the desired output after.
array_walk_recursive($arr, function($v) use (&$res){
$res[]=$v;
});
echo min($res);
Demo
<?php
$GLOBALS["min"] = 999999; //min value int
$arr = [[[5,6],7],9,7,5, 1 , 2, 3, [1,5,59,47,58,[1,12,562]]];
array_walk_recursive($arr, 'NumMin');
function NumMin($item)
{
if(intval($item) <= intval($GLOBALS["min"]))
{
$GLOBALS["min"] = intval($item);
}
}
// The end, $GLOBALS["min"] will have the least value
echo $GLOBALS["min"];
?>

PHP and ordering array items with numbers and texts

I'm using PHP. I have an array which has 1-256 items. Here is an example:
$arr[] = "(1.) Ben";
$arr[] = "Albert";
$arr[] = "Bill";
$arr[] = "(2.) Paul";
$arr[] = "(5.) Martin";
$arr[] = "(12.) Mike";
$arr[] = "(20.) John";
Question 1:
I would like to order the items alphabetically by names. So, the result should be this:
Albert
(1.) Ben
Bill
(20.) John
(5.) Martin
(12.) Mike
(2.) Paul
Question 2:
I also would like to order the items by 1) numbers and 2) names like this way:
(1.) Ben
(2.) Paul
(5.) Martin
(12.) Mike
(20.) John
Albert
Bill
How could I do the job with PHP?
It's sorting for Question 1:
<?php
$arr[] = "(1.) Ben";
$arr[] = "Albert";
$arr[] = "Bill";
$arr[] = "(2.) Paul";
$arr[] = "(5.) Martin";
$arr[] = "(12.) Mike";
$arr[] = "(20.) John";
usort($arr, function($a, $b){
$a = explode(' ', $a, 2);
$a = (count($a) > 1) ? $a[1] : $a[0];
$b = explode(' ', $b, 2);
$b = (count($b) > 1) ? $b[1] : $b[0];
return strcmp($a, $b);
});
print_r($arr); // // Print array sorted for 'Question 1'
#EDIT
And sorting for Question 2:
$arr[] = "(1.) Ben";
$arr[] = "Albert";
$arr[] = "Bill";
$arr[] = "(2.) Paul";
$arr[] = "(5.) Martin";
$arr[] = "(12.) Mike";
$arr[] = "(20.) John";
usort($arr, function($a, $b){
$a = explode(' ', $a, 2);
$b = explode(' ', $b, 2);
if(count($a) > 1 && count($b) > 1)
{
$a = str_replace(['(', ')', '.'], '', $a[0]);
$b = str_replace(['(', ')', '.'], '', $b[0]);
return $a > $b;
}
else
{
return strcmp($a[0], $b[0]);
}
});
print_r($arr); // Print array sorted for 'Question 2'
php got sort functions: asort() for sorting by value and ksort() for sorting by key.
asort($arr); // now sorted by value.
ksort($arr); // now sorted by key.
As you are using index array so u can sort alphabetically by asort() function but for the another questions u have to make a function ie. The order in which u want to sort and then apply uasort() function. Link is php.net/manual/en/functions.uasort.php check the above link u might get clear

Php, in_array with no exactly match

I want to do the following:
$a = array();
$a[] = array(1,2);
$a[] = array(2,5);
$a[] = array(3,4);
var_dump (in_array(array(2,5), $a));
this returns OK, as it expected, but if the source array is not fully matched:
$a = array();
$a[] = array(1,2, 'f' => array());
$a[] = array(2,5, 'f' => array());
$a[] = array(3,4, 'f' => array());
var_dump (in_array(array(2,5), $a));
it returns false. Is there a way to do it with the built-in way, or I have to code it?
in_array() is just not the thing that you should use for this issue. Because it will compare values with type casting, if that's needed. Instead, you may use plain loop or something like:
function in_array_array(array $what, array $where)
{
return count(array_filter($where, function($x) use ($what)
{
return $x===$what;
}))>0;
}
So then
var_dump(in_array_array(array(2, 5), $a)); //true
$needle = array(2, 5);
$found = array_reduce($a, function ($found, array $array) use ($needle) {
return $found || !array_diff($needle, $array);
});
This does an actual test of whether the needle is a subset of an array.
function subset_in_array(array $needle, array $haystack) {
return array_reduce($haystack, function ($found, array $array) use ($needle) {
return $found || !array_diff($needle, $array);
});
}
if (subset_in_array(array(2, 5), $a)) ...

PHP merging arrays uniquely

So i'm working on a small php applications that combines four arrays.
Now there is a possibility that some of the possible arrays will be null.
I tried the following solution to merge the four arrays uniquely.
<?php
$a = [1,2,3,4,5];
$b = null;
$c = [5,4,3,2,1];
$d = [1,2];
$new_array;
if(is_array($a) && is_array($b) && is_array($c) && is_array($d))
{
$new_array = array_unique(array_merge($a,$b,$c,$d));
}else if(is_array($a) && is_array($b) && is_array($c))
{
$new_array = array_unique(array_merge($a,$b,$c));
}else if(is_array($a) && is_array($b))
{
$new_array = array_unique(array_merge($a,$b));
}else{
$new_array = $a;
}
print_r($new_array);
?>
I soon realized my code was highly dysfunctional in that it does not cater for all possible combinations of arrays while excluding the null variables.
How do I solve this. Ensuring that all the variables that are arrays are merged a nd those that are not are discarded.
Thanks
how about this? putting all the array's in an array, so you can loop through them all easily, and use a custom in_array() function to check if they are already existing?
The good thing about this way is that it doesn't limit the script to just four array's, as it will loop through all the array's you get together.
$a = [1,2,3,4,5];
$b = null;
$c = [5,4,3,2,1];
$d = [1,2];
$array_stack = array($a, $b, $c, $d);
$new_array = array();
foreach($array_stack as $stack){
if(!is_array($stack)) continue;
foreach($stack as $value){
if(!in_array($value, $new_array)) $new_array[] = $value;
}
}
print_r($new_array);
maybe something like this :
<?php
$a = [1,2,3,4,5];
$b = null;
$c = [5,4,3,2,1];
$d = [1,2];
$new_array;
if(is_array($a)) $new_array = $a;
if(is_array($b)) $new_array = array_unique(array_merge($new_array,$b));
if(is_array($c)) $new_array = array_unique(array_merge($new_array,$c));
if(is_array($d)) $new_array = array_unique(array_merge($new_array,$d));
?>
Old question, but going to give my input anyways. A more universal approach:
function multiple_array_merge() {
$args = func_get_args();
$array = [];
foreach ($args as $i) {
if (is_array($i)) $array = array_merge($array, $i);
}
return array_unique($array);
}
$a = [1, 2, 3, 4, 5];
$b = null;
$c = [5, 4, 3, 2, 1];
$d = [1, 2];
$merged = multiple_array_merge($a, $b, $c, $d);

PHP: Minimum value in 2D array

I have a 2D array in the format:
[
[1, 23, 20],
[2, 45, 30],
[4, 63, 40],
...
]
I am trying to search the array and return elements [0] and [1] from the row where element [1] is lowest. I have the following code to return the lowest value in [1] but I'm not sure how to get element [0] as well.
$min = PHP_INT_MAX;
foreach ($test as $i) {
$min = min($min, $i[1]);
}
In the above example I would return [1, 23]
Thanks,
You should use usort for this:
usort($test, function($a, $b) {
return $a[1] - $b[1];
});
$min = $test[0];
Note that this uses anonymous functions, which were introduced in PHP 5.3. In previous versions, you need to use named functions and pass the name as a string to usort.
You could use array_reduce:
$array = array(
array(1, 23, 20),
array(2, 45, 63),
array(4, 63, 40),
);
$callback = function ($a1, $a2) {
if ($a1[1] >= $a2[1]) {
return $a2;
} else {
return $a1;
}
}
$min = array_reduce($array, $callback, array(0, PHP_INT_MAX, 0));
var_dump($min); // array(1, 23, 20);
Now, this will likely have issues if you have multiple elements with identical [1] elements... But it transparently handles the case where the array is empty. And in general, all you need to do is do your comparison in the callback function for all "filtering" type problems where you can abstract the filtering to a comparison of 2 elements. So you do string comparison, etc to determine which of the 2 is better...
And it should be more efficient than a sort, since it only requires a single pass over the array (It's O(n) whereas sorting is O(n log n) and at worst O(n^2))...
This will do the job.
$min0 = PHP_INT_MAX;
$min1 = PHP_INT_MAX;
foreach ($test as $i) {
if($i[1] < $min1)
{
$min0 = $i[0];
$min1 = $i[1];
}
}
This will result in $min0 == 1 and $min1 == 23
You'll need to introduce some basic logic:
$result = array(0, PHP_INT_MAX);
foreach($test as $i)
if($i < $result[1])
$result = array($i[0], $i[1]);
You can use a simple min (O(n)) loop like you did, and array_slice to assign the first two indexes when a lowest is found :
$min = PHP_INT_MAX;
$arrMin = array();
foreach ($test as $i) {
if ($i[1] < $min) {
$min = $i[1];
$arrMin = array_slice($i, 0, 2);
}
}
you should just grab the array key of the smallest number:
$min = PHP_INT_MAX;
$minkey = 0;
foreach ($test as $key => $i) {
if($min > $i[1]) {
$min = $i[1];
$minkey = $key;
}
}
then, you can just access the whole thing with $test[$minkey]

Categories