Reputation: 6089
I want to sort whole bunch of keys in an array. The key-value pairs are of a large number and a name. It sorts arrays incorrectly on small numbers and it gets even worse when numbers get too big to be stored as integers. If the integers are too big they are stored as strings in an array. And those strings don't sort at all staying in the same place.
All i want to do is to sort the Key-value pairs from largest to smallest.
I have no idea how to do that since the sorting functions fail completely.
I'll appreciate any help I can get.
Here is my code:
<?php
$encodedNames = $_GET['names']; //names array from a html input encoded with JSON.stringify(nameArray);
$names=json_decode($encodedNames); //decode the names
$namesLegacy = (array) NULL; //array that will store key-value pairs (number=>name)
//for each name gets a large number and assigns it as a key
foreach($names as $name){
$name = trim($name);
array_push($namesLegacy, array(getFameNumber($name)=>$name)) ;
}
echo var_dump($namesLegacy) . "<br />";//dumps the array before it is sorted
krsort($namesLegacy);
echo var_dump($namesLegacy) . "<br />";//dumps the array after its sorted
//simply prints each name in a list format
for ($i = 0; $i < sizeof($namesLegacy); $i++) {
$keys = array_values($namesLegacy[$i]);
echo $i+1 .". ".$keys[0] . "<br/>" ;
}
//gets the large number that will become a key and returns it , as a string ?
function getFameNumber($name)
{
$resultTagId = "resultStats";
$name = str_replace(" ", "+", trim($name));
$url='url that will return the large number';
/*can be tested with google url
$url='http://www.google.com/search?q='.$name.'&ie=utf-8&oe=utf-8&aq=t';*/
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
$data = curl_exec ($ch);
curl_close ($ch);
$dom = new DOMDocument();
@$dom->loadHTML( $data );
$resultsTag = $dom->getElementById($resultTagId)->nodeValue;
$results = preg_replace("/[^0-9]/","",$resultsTag);
return $results;
}
?>
Update: I have run more examples to test if it will sort all non string values correctly and it turns out that it doesnt. (where previously it has worked now it fails) I have an array
array(3) { [0]=> array(1) { [1800000000]=> string(6) "Robert" } [1]=> array(1) { [591000000]=> string(6) "albert" } [2]=> array(1) { [1100000000]=> string(4) "Anna" } }
and when i run krsort() on it it returns
array(3) { [2]=> array(1) { [1100000000]=> string(4) "Anna" } [1]=> array(1) { [591000000]=> string(6) "albert" } [0]=> array(1) { [1800000000]=> string(6) "Robert" } }
which is not the correct result correct result is 1800000000, 1100000000, 591000000
I tried to converting those string into floats but it mostly made them come out as negative numbers. So i tried going the other way converting small ints to strings, but the strange thing is that they were already strings. It seems that they are converted to ints when i form a key value pair inside an array.
anybody knows what is going on? am i using krsort incorrectly is the problem still because the numbers are too big?
also I will give an example of how it looks like when i have a really big number in my array
array(1) { [0]=> array(1) { ["4430000000"]=> string(3) "son" } }
notice the "" marks around the number where in previous arrays its not there
Update2:
Ok so i know it has nothing to do with how big the integers are.
I placed this code to test it $results = substr($results, 0, -3);
but i still get incorrect results
array(3) { [2]=> array(1) { [1550]=> string(5) "Reeta" } [1]=> array(1) { [1800000]=> string(6) "Robert" } [0]=> array(1) { [1090000]=> string(4) "Anna" } }
I also reversed keys and values and tried sorting with arsort()
with same results
If anyone could explain why strings get converted to ints when they are set as keys in the arrays that would be greatly appreciated as well.
here is a krsort manual.
Upvotes: 0
Views: 440
Reputation: 48031
You have an indexed array of associative arrays and your intention seems to be to sort the rows by the variable key in each single-element row. ksort()
and krsort()
will not perform sorting on the second level keys. You will need to isolate those keys while sorting the rows.
An efficient approach implements array_multisort()
. Demo
array_multisort(
array_map(key(...), $array),
$array
);
var_export($array);
Involving more iterated function calls, you can call key()
twice per iteration of usort()
. Demo
usort(
$array,
fn($a, $b) => key($a) <=> key($b)
);
var_export($array);
My test data doesn't indicate any interference from especially long integer or type casting.
Upvotes: 0
Reputation: 4637
Try
$key = getFameNumber($name);
array_push($namesLegacy, array("$key"=>$name)) ;
Upvotes: 0