How to Force PHP to Use Strings for Array Keys

How can I force PHP to use strings for array keys?

EDIT:

I assumed that if they are integers, I
can't reorder them without changing
the key (which is significant in this
example). However, if they were
strings, I can reorder them how they
like as the index shouldn't be
interpreted to have any special
meaning. Anyway, see my question
update for how I did it (I went down a
different route).

Actually they dont have to be in numeric order...

array(208=>'a', 0=> 'b', 99=>'c');

Is perfectly valid if youre assigning them manually. Though i agree the integer keys might be misinterpreted as having a sequential meaning by someone although you would think if they were in a non-numeric order it would be evident they werent. That said i think since you had the leeway to change the code as you updated that is the better approach.


Probably not the most efficient way but easy as pie:

$keys = array_keys($data);

$values = array_values($data);
$stringKeys = array_map('strval', $keys);

$data = array_combine($stringKeys, $values);

//sort your data

A numeric string as array key in PHP

No; no it's not:

From the manual:

A key may be either an integer or a string. If a key is the standard representation of an integer, it will be interpreted as such (i.e. "8" will be interpreted as 8, while "08" will be interpreted as "08").

Addendum

Because of the comments below, I thought it would be fun to point out that the behaviour is similar but not identical to JavaScript object keys.

foo = { '10' : 'bar' };

foo['10']; // "bar"
foo[10]; // "bar"
foo[012]; // "bar"
foo['012']; // undefined!

transform integer array keys to string array keys

This is not possible.

PHP will internally detect that it's a number (even in quotes) and convert it back. If you notice: the original array and the end one are identical. That's because PHP's automatically casting it for you.

The only way to prevent that is to not use numbers. You could prefix the numbers:

$a = [
"_0" => "a",
"_1" => "b",
]

But in general, you don't want to do that. And as you said, it's not even required by the code you thought it was.

And if you are wondering why it casts for you. I have one response. Because:

Because PHP

Convert array keys from numeric string to integer

Propably simplest solution:

$keys = array_keys($data);
$values = array_values($data);

$intKeys = array_map('intval', $keys);

$newData = array_combine($intKeys, $values);

Update:

With checking of key type:

$keys = array_keys($data);
if ($keys === array_filter($keys, 'is_numeric')) {

$data = array_combine(
array_map('intval', $keys),
array_values($data)
);
}

How to add strings to array key if that made by laravel5 pluck(lists) method?

that mistake is the answer lmao XD
truly work this, forgive my stupid.

foreach($months as $key => $value){
$months[$key.'month'] = $value;
unset($months[$key]);
}

P.S.

Above Code is MISTAKE

This Code is true.

foreach($months as $key => $value){
$months[$value] = $value.'month';
}

PHP array with numeric keys as string can't be used

So, I haven't seen any other answers touch upon this, but @xdazz came close.

Let's start our environment, $obj equals the object notation of a decoded string:

php > $obj = json_decode('{"1":1,"2":2}');

php > print_r($obj);
stdClass Object
(
[1] => 1
[2] => 2
)

php > var_dump( $obj );
object(stdClass)#1 (2) {
["1"]=>
int(1)
["2"]=>
int(2)
}

If you want to access the strings, we know the following will fail:

php > echo $obj->1;

Parse error: parse error, expecting `T_STRING' or `T_VARIABLE' or `'{'' or `'$'' in php shell code on line 1

Accessing the object variables

You can access it like so:

php > echo $obj->{1};
1

Which is the same as saying:

php > echo $obj->{'1'};
1

Accessing the array variables

The issue with arrays is that the following return blank, which is the issue with typecasting.

php > echo $obj[1];
php >

If you typecast it back, the object is once again accessible:

php > $obj = (object) $obj;
php > echo $obj->{1};
1

Here is a function which will automate the above for you:

function array_key($array, $key){
$obj = (object) $array;
return $obj->{$key};
}

Example usage:

php > $obj = (array) $obj;
php > echo array_key($obj, 1);
1

php > echo array_key($obj, 2);
2

Fastest way to add prefix to array keys?

I've found that PHPBench is not a very good source for non-trivial benchmarks. So unless your actually interested in running for(....); it's not going to correctly show which syntax will be faster. I've put together a simple benchmark to show that foreach is actually the fastest when your use both the key and value during the iteration.

It's very important to actually force PHP to read the values from a loop iteration, or else it'll do its best to optimize them out. In the example below I use the doNothing function to force PHP to calculate the key and value each time. Using doNothing will cause an overhead to be applied to each loop, but it will be the same for each loop since the number of calls will be the same.

I wasn't really that surprised that foreach came out on top since it's the language construct for iterating a dictionary.

$array = range( 0, 1000000 );

function doNothing( $value, $key ) {;}

$t1_start = microtime(true);
foreach( $array as $key => $value ) {
doNothing( $value, $key );
}
$t1_end = microtime(true);

$t2_start = microtime(true);
$array_size = count( $array );
for( $key = 0; $key < $array_size; $key++ ) {
doNothing( $array[$key], $key );
}
$t2_end = microtime(true);

//suggestion from PHPBench as the "fastest" way to iterate an array
$t3_start = microtime(true);
$key = array_keys($array);
$size = sizeOf($key);
for( $i=0; $i < $size; $i++ ) {
doNothing( $key[$i], $array[$key[$i]] );
}
$t3_end = microtime(true);

$t4_start = microtime(true);
array_walk( $array, "doNothing" );
$t4_end = microtime(true);

print
"Test 1 ".($t1_end - $t1_start)."\n". //Test 1 0.342370986938
"Test 2 ".($t2_end - $t2_start)."\n". //Test 2 0.369848966599
"Test 3 ".($t3_end - $t3_start)."\n". //Test 3 0.78616809845
"Test 4 ".($t4_end - $t4_start)."\n"; //Test 4 0.542922019958

Edit: I'm using PHP 5.3 on 64-bit Mac OSX 10.6



Related Topics



Leave a reply



Submit