Most matching array value - php

$mostmatched = function( $input to test, $array with given values)
The array contains diffrent numbers (10,30,50 ...) and I give an input (13) and the desired function should return the nearest value in the array (10).
Is there already a function like this? Else: Any suggestions how to achieve that?

usort($array, function ($a, $b) use ($input) {
return abs($input - $a) - abs($input - $b);
});
echo "Closest: $array[0]";
In other words: take the difference between $input and each value—smaller differences are closer—and sort the array by this. See https://stackoverflow.com/a/17364128/476 if this requires explanation.
Alternatively, simply loop through the array, keep track of the last smallest difference and replace it if you find a smaller difference. I'll leave the implementation of that as an exercise for the reader.

Related

re-order array according to the each hash value

I have array like
$a = $b = $c = [];
$a['num'] = 10;
$b['num'] = 2;
$c['num'] = 4;
$arr = array($a,$b,$c);
then now I want to order array $arr by hash ['num']
result should be array($b,$c,$a)
I think I can re-order by for loop, but it looks not cool.
I think python has list in list but is it possible in PHP?
Is there any good idea to make this??
There is no easy way to do solve this problem. Basically you have to compare the elements inside the array.
You can just use usort function with your custom comparison function.
function compare($a, $b) {
return $a['num'] - $b['num'];
}
usort($arr,"compare");
You can also give an anonymous compare function to it. If you do not plan use your custom compare function again, I recommend you to use anonymous function.
usort($arr,function($a, $b){
return $a['num'] - $b['num'];
});
Do not forget
usort function does not return an array. It just returns TRUE on success or FALSE on fail and the array that you send as a parameter will sort.
You can use sort().
sort($arr);
The inner arrays are the same length, and all have the same single key, so sort() will compare them based on their contents and $arr will be sorted as if it was simply an array of integers.

sort an array on maximum occurrences

I'm new to php and I feel that this language has some really good set of sorting functions for arrays
I have an input array below containing the books , readers and price
$input[]=array("Harrypotter","John",50);
$input[]=array("Twilight","John",60);
$input[]=array("Harrypotter","Jack",80);
$input[]=array("Gonegirl","marion",90);
$input[]=array("Gonegirl","test",90);
$input[]=array("Gonegirl","John",90);
$input[]=array("Gonegirl","eliza",90);
I want to sort the array on first field in such a way that the book which repeats more number of times should come first , the expected O/p is something like this
$input[]=array("Gonegirl","marion",90);
$input[]=array("Gonegirl","test",90);
$input[]=array("Gonegirl","John",90);
$input[]=array("Gonegirl","eliza",90);
$input[]=array("Harrypotter","Jack",80);
$input[]=array("Harrypotter","John",50);
$input[]=array("Twilight","John",60);
I'm able to copy the first field in separate array and get the occurrence by using array_count_values and i'm able to get the expected output through array_multi_sort but it sorts only by alphabetical order of the first field .
Any efficient way of arriving at the solution would be helpful !
You will first have to establish a count of how often each value occurs, then you can write a comparison function that sorts by those values:
$counts = array_count_values(array_map('current', $input));
usort($input, function (array $a, array $b) use ($counts) {
return $counts[$b[0]] - $counts[$a[0]];
});
This should work for you:
<?php
$input = array();
$input[]=array("Harrypotter","John",50);
$input[]=array("Twilight","John",60);
$input[]=array("Harrypotter","Jack",80);
$input[]=array("Gonegirl","marion",90);
$input[]=array("Gonegirl","test",90);
$input[]=array("Gonegirl","John",90);
$input[]=array("Gonegirl","eliza",90);
function cmp($a, $b) {
return strcmp($a[0], $b[0]);
}
usort($input, "cmp");
print_r($input);
?>
array_multisort(array_map('count', $input), SORT_DESC, $input);
PS: From PHP Sort a multidimensional array by number of items
Update:
array_multisort(array_map(function ($fld) {return $fld[0];}, $input), SORT_ASC, $input);

Sort array based on substring following a specific character, then by the substring before the character

I need to re-order the elements in my array by the number after the "R" and then the first part.
I have a array with the following elements.
215/75R17.5
235/75R17.5
8.25R16
7.00R16
11R22.5
7.50R16
so to this:
7.00R16
7.50R16
8.25R16
11R22.5
215/75R17.5
235/75R17.5
First of all this is obviously going to be a custom comparison; the go-to function for that is usort, which accepts a custom comparison as an argument.
The custom comparison function would be like this:
function customCompare($x, $y) {
$x = explode('R', $x);
$y = explode('R', $y);
if ($x[1] != $y[1]) return $x[1] < $y[1] ? -1 : 1;
return strnatcmp($x[0], $y[0]);
}
See it in action.
How it works
First we split each input string on the character R, producing an array such as ['8.25', '16'] from a string such as '8.25R16'. In each array the second element is the diameter (first sort criterion) and the first is the width (second criterion).
If the diameters are different then we immediately pass judgement based on that.
If the diameters are equal then we use strnatcmp to compare the widths -- this is so that a width of 100 is larger than a width of 20 (a dumb ASCII comparison would produce the opposite result).
No matter how you decide to isolate the substring that follows R, you should try to minimize the number of times that function calls are made.
Using array_multisort() with mapped calls of the isolating technique will perform better than a usort() approach because usort() will perform the isolating technique multiple times on the same value.
In my snippet below, I do not remove the R while isolating, so I use natural sorting to have the numeric substrings compared correctly. If you aren't familiar with strpbrk() then see this answer for a demonstration.
Code: (Demo)
$array = [
'215/75R17.5',
'235/75R17.5',
'8.25R16',
'7.00R16',
'11R22.5',
'7.50R16'
];
array_multisort(array_map(fn($v) => strpbrk($v, 'R'), $array), SORT_NATURAL, $array);
var_export($array);
An approach that purely isolates the numeric values will not need to sort naturally. (Demo)
array_multisort(array_map(fn($v) => sscanf($v, '%*[^R]R%f')[0], $array), $array);
var_export($array);

Find the most recent date from a nested array

I have a Multilevel Array (See array structure picture below) and I need to get the sub-nested array with the higher date value.
I was wondering if there is a straight forward way to sort sub-nested arrays by date value or get the highest date value?
Array Map
To do that, usort() function will be useful:
usort($rgData, function($rgX, $rgY)
{
$x = strtotime($rgX['date']);
$y = strtotime($rgY['date']);
return $x<$y?-1:$x!=$y;
});
//var_dump($rgData);
if you want to get highest value, then it will be ['date'] key of last element after doing the sort above.
Edit: if you're sure that format will be exactly same as on picture always, you can use direct string comparison via strcmp (that would be probably faster)
How about using usort():
$input = array(
array('date' => '2013-09-11 13:08:40 +0000'),
array('date' => '2013-09-11 13:09:17 +0000'));
usort($input, function(array $a, array $b) {
$aTimestamp = strtotime($a['date']);
$bTimestamp = strtotime($b['date']);
if($aTimestamp == $bTimestamp) return 0;
return $aTimestamp < $bTimestamp;
});
print_r($input); //$input[0] has the latest date value

PHP array sort()

Im stuck on a sorting problem, I have an array with 10 numbers (1-10) and I need to sort the in the following way where 10 would come after 1, for example...
desired outcome
$arr['a1','a10','a2','a3','a4','a5','a6','a7','a8','a9'];
actual outcome
$arr['a1','a2','a3','a4','a5','a6','a7','a8','a9','a10'];
sort($arr);
$arr['a10','a1','a2','a3','a4','a5','a6','a7','a8','a9'];
I don't know the name of this type of sorting or how to perform it, if anyone could help me it would much appreciated.
NOTE: the numbers are part of a string
Try sort($arr,SORT_STRING) to explicitly treat the input as strings.
EDIT: Now that you've given your actual strings, try this:
usort($arr,function($a,$b) {
$a = explode("=",$a);
$b = explode("=",$b);
return $a[0] == $b[0] ? strcmp($a[1],$b[1]) : strcmp($a[0],$b[0]);
});
Sure, you want to sort alphabetically, not numerically.
sort($arr, SORT_STRING);
ref: http://php.net/manual/en/function.sort.php
You can change the behaviour of sort with it's second parameter.
Try this:
sort($arr, SORT_STRING);

Categories