4

I have an array with ID's as the key and a name from a database associated with it. I use this to get statistics from PHP for output to a Google Chart generated in JavaScript (through JSON). In PHP I have the following array:

$a = [ 
  '33' => 'first',
  '25' => 'second',
  '14' => 'last
];

If I run the following code:

foreach( $a as $key => $val )
   echo "$key => $val" . PHP_EOL;

I get the following (expected) result

   33 => first
   25 => second
   14 => last

I use AJAX and JSON to send this to a JavaScript environment, here it becomes an object. Now when I run the following JavaScript:

for( var i in a )
   console.log( i + " => " + a[i] );

I get

   14 => last
   25 => second
   33 => first

so my keys are interpreted as integers and sorted in JavaScript, which in this case means the array with statistics I was sending to Google Chart is matching up with the wrong labels.

I solved this by sorting the array in PHP before I read the statistics from the database. I needed the keys to stay the same though, this is what I did in PHP:

 $tmp = array_flip( $a );
 asort( $tmp );
 $a = array_flip( $tmp );

this gives me the array in PHP like this:

[
   '14' => 'last',
   '25' => 'second',
   '33' => 'first'
]

so now a foreach in PHP will have the same order as a for( i in ...) in JavaScript. I was wondering if there is either a nicer way of sorting my array in PHP instead of flipping it twice -or- if there's an option for a loop in JavaScript that doesn't order the (admittedly confusing) integer value keys of my array?

patrick
  • 10,664
  • 7
  • 58
  • 75
  • Anyway, wouldn't you prefer making something so that the array isn't sorted on JS side and you can loop through it the way it was supposed to be? – diego nunes Jul 23 '16 at 03:01
  • yes, that's why I posted the whole case here. I was a bit bummed out that PHP's foreach was so different from JavaScripts for( var i in... – patrick Jul 23 '16 at 03:03
  • Some browsers implements objects/arrays with key-sorting and there is nothing you can do to change that. You can, however, use an array (with pairs inside) rather than an object. – diego nunes Jul 23 '16 at 03:23

2 Answers2

2

Have you tried ksort?

ksort

(PHP 4, PHP 5, PHP 7) ksort — Sort an array by key

Description

bool ksort ( array &$array [, int $sort_flags = SORT_REGULAR ] ) Sorts an array by key, maintaining key to data correlations. This is useful mainly for associative arrays.

If it doesn't deal well with numeric-strings keys you can use uksort and write your compare function with a parseInt and spaceship operator (<=>).


If you, however, want to simply stop the reordering fully, altought you can't stop the "sorting" of the object by its keys (and note that it is not standard and is browser-dependent: not all of them will sort it), you can always use pairs inside an array to avoid changes to your original order of elements (pairs, in this case):

$a = [ ['33', 'first'], ['25', 'second'], ['14', 'last'] ];

Community
  • 1
  • 1
diego nunes
  • 2,360
  • 1
  • 10
  • 16
1

All you need:

ksort($a)

Result:

[
    14 => 'last',
    25 => 'second',
    33 => 'first',
]
BeetleJuice
  • 33,709
  • 16
  • 78
  • 137
  • that makes a lot more sense... In one attempt I tried this and killed the index with it (ended up with [0=>'last', 1=>'second', etc).. I tried this again and it worked. I must have done something wrong that first time. Thanks for this answer! – patrick Jul 23 '16 at 02:59