Reputation: 11391
Due to serialization/deserialization of arrays I get incorrect data type of array keys in some cases.
$data = [
0 => 'item 1',
4 => 'item 2',
7 => 'item 3',
];
$storage->set( 'demo', $data );
// ...and get it back later
$data = storage->get( 'demo' );
var_dump( $data );
/*
Result:
array (size=3)
"0" => string "item 1"
"4" => string "item 2"
"7" => string "item 3"
But I need (keys must be int):
array (size=3)
0 => string "item 1"
4 => string "item 2"
7 => string "item 3"
*/
Question: Is there an easy way to convert the keys back to integer?
I tried array_reverse( array_map( 'intval', array_reverse( $data ) ) )
but this loses items with different keys but identical values and most importantly it has problems with non-numeric keys.
Also array_values( $data )
did not solve the problem due to similar problems: It loses non-numeric keys and also keys are not sequential (it can be 0, 4, 7
, but array_values()
will assign keys 0, 1, 2
)
Update - why this is important for my
We had problems with some website configuration because of this:
$data['0']
returns 'item1'
but$data[0]
returns null
Upvotes: 2
Views: 13497
Reputation: 41400
PHP documentation
Additionally the following key casts will occur:
Strings containing valid decimal ints, unless the number is preceded by a + sign, will be cast to the int type. E.g. the key "8" will actually be stored under 8. On the other hand "08" will not be cast, as it isn't a valid decimal integer.
So you can use it, you don't need to check any conditions
Upvotes: 2
Reputation: 4244
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)
);
}
Upvotes: 3
Reputation: 11391
Thanks to this great suggestion https://stackoverflow.com/a/45505894/313501 I came up with this code:
// Convert array keys to integer values, if array only contains numeric keys.
$is_numeric = array_reduce(
array_keys( $data ),
function( $res, $val ) { return $res && is_numeric( $val ); },
true
);
if ( $is_numeric ) {
$data = array_combine(
array_map( 'intval', array_keys( $data ) ),
array_values( $data )
);
}
Upvotes: 0
Reputation: 5868
You can use is_numeric
and intval
to convert the keys:
$data2 = array();
foreach($data as $key=>$value) {
$key2 = is_numeric($key) ? intval($key) : $key;
$data2[$key2] = $value;
}
var_dump( $data2 );
Upvotes: 1