15.04.2020, 03:58
|
Профессор
|
|
Регистрация: 14.01.2015
Сообщений: 12,990
|
|
Трескотня пустая.
Массив в PHP - это упорядоченное отображение, которое устанавливает соответствие между значением и ключом. Этот тип оптимизирован в нескольких направлениях, поэтому вы можете использовать его как собственно массив, список (вектор), хэш-таблицу (являющуюся реализацией карты), словарь, коллекцию, стэк, очередь и т.п.
Ключ может быть либо типа integer, либо типа string. Значение может быть любого типа. Дополнительно с ключом будут сделаны следующие преобразования:
◦ Строки, содержащие целое число будут преобразованы к типу integer. Например, ключ со значением "8" будет в действительности сохранен со значением 8. С другой стороны, значение "08" не будет преобразовано, так как оно не является корректным десятичным целым.
◦ Числа с плавающей точкой (тип float) также будут преобразованы к типу integer, т.е. дробная часть будет отброшена. Например, ключ со значением 8.7 будет в действительности сохранен со значением 8.
◦ Тип bool также преобразовываются к типу integer. Например, ключ со значением true будет сохранен со значением 1 и ключ со значением false будет сохранен со значением 0.
◦ Тип null будет преобразован к пустой строке. Например, ключ со значением null будет в действительности сохранен со значением "".
◦ Массивы (тип array) и объекты (тип object) не могут использоваться в качестве ключей. При подобном использовании будет генерироваться предупреждение: Недопустимый тип смещения (Illegal offset type).
Если несколько элементов в объявлении массива используют одинаковый ключ, то только последний будет использоваться, а все другие будут перезаписаны.
Тоже самое будет и в JS, если var o = {1: 1, '1': 2}, то в результате будет одно свойство со значением 2. И речь шла о массивах и объектах. JS, это не нечто исключительное, в других языках тоже всякой хрени полно, сравнивать их, это если делать нехер и времени свободного хоть отбавляй, а если охота, пожалуйста.
Последний раз редактировалось laimas, 15.04.2020 в 04:04.
|
|
15.04.2020, 15:01
|
|
Профессор
|
|
Регистрация: 20.12.2009
Сообщений: 1,714
|
|
Сообщение от Белый шум
|
Нет такого правила, что ассоциативный массив обязан различать числа от строк с этим числом.
|
Однако в большинстве языков программирования (если говорить об ассоциативных массивах) такое различие делается, т. к. числа и строки — это разные типы.
А вот объект языка программирования (даже если говорить о языках с нестрогой типизацией), который можно рассматривать как коллекцию пар (строка, значение), как раз не делает различия между числом и строками с этим числом — происходит приведение имени свойства/поля/метода к строковому значению.
Сообщение от Белый шум
|
Для языков с нестрогой типизацией такое поведение является ожидаемым.
|
Совершенно нет! Просто вы путаете динамический объект/объект представляющий класс с ассоциативным массивом.
Сообщение от laimas
|
Ключ может быть либо типа integer, либо типа string. Значение может быть любого типа.
|
Ключ типа integer неявно приводится к строке, поскольку вы не можете использовать такой же ключ типа string. То, что вы описали — это объект языка программирования. Учитывая, что можно менять его свойства как угодно — это как dynamic object в C# или Object.create(null) в JS.
Сообщение от laimas
|
Дополнительно с ключом будут сделаны следующие преобразования:
|
Сообщение от laimas
|
т.е. дробная часть будет отброшена.
|
Сообщение от laimas
|
Тип bool также преобразовываются к типу integer.
|
Сообщение от laimas
|
Массивы (тип array) и объекты (тип object) не могут использоваться в качестве ключей.
|
И как такое может называться ассоциативным массивом в PHP? Какое тут может быть соответствие одного значения (ключа) к другому значению, когда ключи безвозвратно утрачивают информацию, порождая коллизии?
Вот класс DS\Map в PHP — это действительно работает как ассоциативный массив, имеет методы для работы с ним. (Также Map в JS, Dictionary в C#, HashMap в Java и пр.)
А то, что в PHP возвращает array() — это даже не массив (некоторые там разглядели список, вектор, хэш-таблицу, словарь, коллекцию, стэк, очередь), а просто динамический объект, у которого даже нет своих методов для работы... Этот динамический объект можно расширять какими угодно свойствами, массивом он от этого не станет.
Этот динамический объект некоторым кажется массивом, однако стоит учитывать, что он таким кажется от того, что его передают в различные глобальные функции типа array_*, count и пр. которые имитируют работу этого т. н. «массива»/«ассоциативного массива»/«вектора» и пр.
Сообщение от laimas
|
Тоже самое будет и в JS, если var o = {1: 1, '1': 2}, то в результате будет одно свойство со значением 2.
|
Конечно — это же динамический объект, как array() в PHP.
Сообщение от Белый шум
|
Поддержка ассоциативных массивов есть во многих интерпретируемых языках программирования высокого уровня... PHP
|
Да, действительно есть!
<?php
$a = new DS\Map();
$a -> put(3, 1);
$a -> put('3', 2);
print_r($a);
// Ds\Map Object
// (
// [0] => Ds\Pair Object
// (
// [key] => 3
// [value] => 1
// )
// [1] => Ds\Pair Object
// (
// [key] => 3
// [value] => 2
// )
// )
print_r($a -> count());
// 2
Сообщение от Белый шум
|
обязан различать числа от строк с этим числом
|
Это вы наверное пристально вглядываетесь в вывод от print_r — он действительно не различает строки и числа, как в примере выше, но сами объекты правильного типа!
|
|
15.04.2020, 15:17
|
Профессор
|
|
Регистрация: 14.01.2015
Сообщений: 12,990
|
|
Пурга словесная, ведь изначально речь шла только о массивах и объектах. А ассоицатитвный массив, это ни как не 1 и "1" ключи, это "a", "b", ... ключи. И такой массив, наряду с индексным, имеет тот же набор функций, а в JS "аналог" нет, ибо это объект. А "просто динамический объект, у которого даже нет своих методов для работы...", это воспаленный бред, если только не рассматривать его как и "есть ли определение индекса в js массиве" для словоблудия.
Кроме этого результат работы функций может отличаться от типа ключей массива. Хотя это может и показаться странным, но такое поведение имеет плюсы, например при объединении запросов в БД.
Любишь ты языком чесать, надоел уже.
|
|
15.04.2020, 15:53
|
|
Профессор
|
|
Регистрация: 19.01.2012
Сообщений: 505
|
|
Сообщение от Malleys
|
Сообщение от Белый шум
|
Нет такого правила, что ассоциативный массив обязан различать числа от строк с этим числом.
|
Однако в большинстве языков программирования...
|
Что там в большинстве языков - не имеет значения, тем более что запрета на такие различия тоже нет.
Если что-то соответствует определению ассоциативного массива, значит оно им и является. Всё остальное - такая же демагогия, как и про отсутствие понятия индексов в javascript :
Сообщение от Malleys
|
Если в спецификации говорится об индексах, то понятие определённо есть!
|
Сообщение от https://www.php.net/manual/en/language.types.array.php
|
PHP arrays can contain integer and string keys at the same time as PHP does not distinguish between indexed and associative arrays.
|
|
|
15.04.2020, 17:52
|
|
Профессор
|
|
Регистрация: 20.12.2009
Сообщений: 1,714
|
|
laimas, Белый шум, смотрите, я например в С# (Unity3D) могу описать отношения между игроком (класс GameObject) и питомцем (класс GameObject)
var pets = new Dictionary<GameObject, GameObject>();
T. е. в качестве ключей используется экземпляр класса GameObject. И зная игрока, я могу получить его питомца.
Теория теорией, однако на практике это в PHP не работает...
<?php
class GameObject {
public $name;
function __construct($name) {
$this->name = $name;
}
}
$laimas = new GameObject("laimas");
$cock = new GameObject("петушок — золотой гребешок");
$malleys = new GameObject("Malleys");
$dino = new GameObject("T-rex");
$pets = [
$laimas => $cock,
$malleys => $dino
];
print_r($pets);
Код:
|
PHP Warning: Illegal offset type in php-omg.php on line 18
PHP Warning: Illegal offset type in php-omg.php on line 19
Array
(
) |
|
|
16.04.2020, 03:00
|
|
Профессор
|
|
Регистрация: 19.01.2012
Сообщений: 505
|
|
Сообщение от Malleys
|
однако на практике это в PHP не работает...
|
Это, конечно, печально, но означает ли это что массивы в PHP не соответствуют определению ассоциативных массивов? Разработчики PHP считают, что не означает...
|
|
21.04.2020, 18:07
|
|
Профессор
|
|
Регистрация: 20.12.2009
Сообщений: 1,714
|
|
Сообщение от Белый шум
|
но означает ли это что массивы в PHP не соответствуют определению ассоциативных массивов?
|
Да, не соответствуют. В РНР — это только частично ассоциативный массив, т. е. его ключи ограничены типом строка, что означает, что он ничем не отличается от экземпляра класса Object в JS.
Зачем вообще в РНР упоминается в связи с [] или array() название ассоциативный массив — неясно, почему нельзя называть вещи своими именами — динамический объект, экспандо (оно ведь и есть объект-распашонка) или расширяемый null. Функции json_encode и json_decode могут показать это!
[] или array() не могут произвести ничего такого, чего нельзя было бы представить при помощи JSON.
Сообщение от Белый шум
|
Разработчики PHP считают, что не означает...
|
Разработчики PHP считают и многие другие нетрадиционные и странные вещи нормальными...
Код:
|
php > print_r((string)247 > '0000247' ? 'Это норма — говорит PHP' : 'Нет');
Нет
php > print_r((string)247 < '0000247' ? 'Это норма — говорит PHP' : 'Нет');
Нет
php > print_r((string)247 == '0000247' ? 'Это норма — говорит PHP' : 'Нет');
Это норма — говорит PHP
php > print_r((string)247 === '0000247' ? 'Это норма — говорит PHP' : 'Нет');
Нет |
Т. е. для PHP условие — '247' > '0000247' неверно, а равенство '247' == '0000247' верно. Это значит, что PHP... «Разработчики PHP считают, что не означает...»
Код:
|
php > print_r(-4.8 > NULL ? 'Это норма — говорит PHP' : 'Нет');
Это норма — говорит PHP |
Учитывая, что в PHP любая переменная может возникнуть в любом месте (с тем самым значением NULL) и даже не произойдёт завершение с ошибкой, означает ли, что PHP... «Разработчики PHP считают, что не означает...» Это норма — говорит PHP, что NULL ведёт себя как −∞.
Много ещё есть вещей типа «Это норма — говорит PHP», однако однажды случилось такое... Я думаю, что в PHP стоило ожидать, что нечто такое произойдёт — T_PAAMAYIM_NEKUDOTAYIM. Если в традиционных языках написали бы в ошибке T_DOUBLE_COLON, то в PHP проявляется неконсистентность даже среди языков, на которых именуются операторы языка. Это означает, что в PHP... Ах, простите, «Разработчики PHP считают, что не означает...» Это норма — говорит PHP.
|
|
21.04.2020, 18:43
|
|
Профессор
|
|
Регистрация: 19.01.2012
Сообщений: 505
|
|
Сообщение от Malleys
|
Да, не соответствуют.
|
Просто найдите общее определение ассоциативного массива, которое соответствует вашему пониманию, и на этом закончим.
В тех определениях, которые встречались мне, говорилось либо о ключах-строках, либо о самом понятии ассоциативности:
т.е. если массив заточен не на последовательные числа, а на произвольные значения в ключах (любого типа), то его можно назвать ассоциативным (иными словами, если массив поддерживает только объекты в качестве ключей, то он всё-равно ассоциативный).
http://kvodo.ru/associative-array.html
|
|
21.04.2020, 19:23
|
|
Профессор
|
|
Регистрация: 20.12.2009
Сообщений: 1,714
|
|
Белый шум, это всё верно и статья хорошая (с примером на C++ — map <string, string> library;). Но причём тут PHP?
PHP с его объектом совсем не соответствует тому, что там описано...
Берём null ($notDefined не объявлен) и расширяем его...
Код:
|
php > $notDefined['notDefined'][2]['person']['isCrazy'] = TRUE;
php > print_r($notDefined);
Array
(
[notDefined] => Array
(
[2] => Array
(
[person] => Array
(
[isCrazy] => 1
)
)
)
) |
Этот null ведёт себя как proxy, поэтому «похапешники» вообразили, что это «ассоциативный массив», однако, например, я недавно обнаружил, что он может вести себя и как −∞.
|
|
21.04.2020, 19:48
|
|
Профессор
|
|
Регистрация: 19.01.2012
Сообщений: 505
|
|
Malleys,Просто найдите общее определение ассоциативного массива, которое соответствует вашему пониманию, и на этом закончим.
|
|
|
|