Подтвердить что ты не робот

Как заставить PHP использовать строки для ключей массива?

Я столкнулся с старым приложением, которое использует идентификатор для имен массива типов, например...

array(1) {
  [280]=>
  string(3) "abc"
}

Теперь мне нужно изменить порядок, и var_dump() будет казаться, что это не произойдет, когда ключи целые.

Если я добавлю a к каждому индексу, var_dump() покажет двойные кавычки вокруг ключа, я думаю, что теперь это строка...

array(1) {
  ["280a"]=>
  string(3) "abc"
}

Это позволит мне легко переупорядочить их, не касаясь большего количества кода.

Это означает, что не работает.

$newArray = array();
foreach($array as $key => $value) {
   $newArray[(string) $key] = $value;
}

A var_dump() все еще показывает их как целые индексы массива.

Есть ли способ заставить клавиши быть строками, поэтому я могу изменить порядок их, не разрушая массив?

4b9b3361

Ответ 1

ИЗМЕНИТЬ

Я предположил, что если они целые, я не могут изменять их без изменения ключ (что важно в этом пример). Однако, если бы они были строки, я могу переупорядочить их, как они как индекс не должен быть интерпретируются как имеющие имея в виду. В любом случае, см. Мой вопрос обновить, как я это сделал (я спустился другой маршрут).

На самом деле они не должны быть в числовом порядке...

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

Совершенно верно, если вы назначили их вручную. Хотя я согласен, что целые ключи могут быть неверно истолкованы как имеющие последовательный смысл кем-то, хотя вы бы подумали, что если бы они были в нечисловом порядке, было бы очевидно, что они не были уверены. Это говорит, что я думаю, так как у вас была свобода, чтобы изменить код по мере обновления, это лучший подход.


Вероятно, это не самый эффективный способ, но простой как пирог:

$keys = array_keys($data);

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

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

//sort your data

Ответ 2

как насчет этого?

$newArray = array();
foreach($oldArray as $key => $value) {
   $newArray[$key.''] = $value;
}

изменить: тоже пробовал и да, это не сработало.

Из Документы PHP:

Ключ может быть либо целым, либо строка. Если ключ является стандартным представление целого числа, это будет интерпретироваться как таковое (т.е. "8" интерпретироваться как 8, а "08" - интерпретироваться как "08" ). Поплавки в ключе усекаются до целого. Нет различные индексированные и ассоциативные типы массивов в PHP; здесь только один тип массива, который может содержать целочисленные и строковые индексы.

Я думаю, теперь это зависит от того, как вы хотите отсортировать массив. (окончательный выход?)

Ответ 3

Используйте объект вместо массива $object = (object)$array;

Ответ 4

Мне удалось заставить это работать, добавив '.0' в конец каждой клавиши:

$options = [];
for ($i = 1; $i <= 4; $i++) {
    $options[$i.'.0'] = $i;
}

Вернется:

array("1.0" => 1, "2.0" => 2, "3.0" => 3, "4.0" => 4)

Он может быть не совсем оптимальным, но он позволяет вам сортировать массив и извлекать (эквивалент) исходный ключ без необходимости урезать что-либо.

Ответ 5

ВЫ НЕ МОЖЕТЕ!

Строки, содержащие действительные целые числа, будут переданы в целочисленный тип. Например. ключ "8" будет фактически сохранен под 8. С другой стороны, "08" не будет выбрано, так как оно не является допустимым десятичным целым.

Изменить:

НАСТОЯЩИМ ВЫ МОЖЕТЕ! Передача последовательного массива в ассоциативный массив

$obj = new stdClass;
foreach($array as $key => $value){
    $obj->{$key} = $value;
}
$array = (array) $obj;

В большинстве случаев следующая цитата верна.

Строки, содержащие действительные целые числа, будут переданы в целочисленный тип. Например. ключ "8" будет фактически сохранен под 8. С другой стороны, "08" не будет выбрано, так как оно не является допустимым десятичным целым.

Эти примеры из Документов PHP

 <?php
    $array = array(
        1    => "a",
        "1"  => "b",
        1.5  => "c",
        true => "d",
    );
    var_dump($array);
?>

Вышеприведенный пример выводит:

array(1) {
  [1]=> string(1) "d"
}

Итак, даже если вы должны были создать массив с пронумерованными клавишами, они просто вернутся к целым числам.

К сожалению, для меня я не знал об этом до недавнего времени, но, хотя я бы поделился своими неудачными попытками.

Неудачные попытки

$arr = array_​change_​key_​case($arr); // worth a try. 

Возвращает массив со всеми ключами из массива с нижним или верхним регистром. Нумерованные индексы остаются как.

Мои последующие попытки состояли в том, чтобы создать новый массив array_combine, используя старые значения, новые (строковые) ключи.

Я попробовал несколько способов сделать массив $keys содержащим числовые значения строки типа.

range("A", "Z" ) работает для алфавита, поэтому, хотя я бы попробовал его с числовой строкой.

$keys = range("0", (string) count($arr) ); // integers

В результате появился массив, полный ключей, но все они были типа int.

Вот несколько успешных попыток создания массива со значениями строки типа.

$keys = explode(',', implode(",", array_keys($arr))); // values strings

$keys = array_map('strval', array_keys($arr)); // values strings

Теперь просто чтобы объединить два.

$arr = array_combine( $keys, $arr); 

Это когда я обнаружил, что числовые строки отлиты от целых чисел.

$arr = array_combine( $keys, $arr); // int strings
//assert($arr === array_values($arr)) // true. 

Единственный способ изменить ключи к строкам и сохранить их литеральные значения - это префикс ключа с суффиксом с десятичной точкой "00","01","02" или "0.","1.","2.".

Вы можете добиться этого так.

$keys = explode(',', implode(".,", array_keys($arr)) . '.'); // added decimal point 
$arr = array_combine($keys, $arr);

Конечно, это не так идеально, как вам нужно будет таргетировать элементы массива, подобные этому.

$arr["280."]   

Я создал небольшую функцию, которая будет нацелена на правильный элемент массива, даже если вы вводите целое число, а не новую строку.

function array_value($array, $key){

    if(array_key_exists($key, $array)){
        return $array[ $key ];
    }
    if(is_numeric($key) && array_key_exists('.' . $key, $array)){
        return $array[ '.' . $key ];
    } 
    return null;
}

Использование

echo array_value($array, "208"); // "abc"

Изменить:

НАСТОЯЩИМ ВЫ МОЖЕТЕ! Передача последовательного массива в ассоциативный массив

Все, что ни за что

Ответ 6

Вы можете добавить нулевой символ "\0" в конец ключа массива. Это делает так, что PHP не может интерпретировать строку как целое. На нем работают все функции массива (например, array_merge()). Кроме того, даже var_dump() покажет что-нибудь лишнее после цепочки целых чисел.

Пример:

$numbers1 = array();
$numbers2 = array();
$numbers = array();

$pool1 = array(111, 222, 333, 444);
$pool2 = array(555, 666, 777, 888);

foreach($pool1 as $p1)
{
    $numbers1[$p1 . "\0"] = $p1;
}
foreach($pool2 as $p2)
{
    $numbers2[$p2 . "\0"] = $p2;
}

$numbers = array_merge($numbers1, $numbers2);

var_dump($numbers);

Результирующий результат будет:

array(8) {
    ["111"] => string(3) "111"
    ["222"] => string(3) "222"
    ["333"] => string(3) "333"
    ["444"] => string(3) "444"
    ["555"] => string(3) "555"
    ["666"] => string(3) "666"
    ["777"] => string(3) "777"
    ["888"] => string(3) "888"
}

Без части . "\0" результирующий массив будет:

array(8) {
    [0] => string(3) "111"
    [1] => string(3) "222"
    [2] => string(3) "333"
    [3] => string(3) "444"
    [4] => string(3) "555"
    [5] => string(3) "666"
    [6] => string(3) "777"
    [7] => string(3) "888"
}

Также ksort() также игнорирует значение нулевого символа $numbers[111] и $numbers["111\0"] будет иметь одинаковый вес в алгоритме сортировки.

Единственным недостатком этого метода является то, что для доступа, например $numbers["444"], вам действительно нужно получить к нему доступ через $numbers["444\0"], и поскольку даже var_dump() покажет вам там нулевой символ в конце, не знаю, почему вы получаете "Undefined offset". Поэтому используйте этот хак, если итерация через foreach() или тот, кто закончит поддерживать ваш код, будет вас ненавидеть.

Ответ 7

Изменить: Это должно работать

foreach($array as $key => $value) { 
    $newkey = sprintf('%s',$key);
    $newArray["'$newkey'"] = $value; 
}