Удаление элементов из массива

Фанат

oncle terrible
Команда форума
Еще скажи что программист, который приписал себе TDD Infected не понимает разницу между массивом и хэшем.
А ты не ему писал, вообще-то. А человеку, который слово массив два дня назад узнал =)
и пугаешь его страшными словами хэш и итератор.

Отвечая на этом форуме ,проще надо быть. Сильно проще.
Вот, как я! =)
 

Andreika

"PHP for nubies" reader
whirlwind
>и в каком собственно ЯП после удаления элемента массива магическим образом остальные будут сдвинуты?

ща для тя откроется страшная тайна.. приготовься

PHP:
$a = array('a','b','c','d');
array_splice($a,2,1);
print_r($a);
 

zerkms

TDD infected
Команда форума
whirlwind
на той же самой странице википедии:

"для статического массива — отсутствие динамики, невозможность удаления или добавления элемента без сдвига других "

а про итератор - при модификации данных итератор "устаревает", это общеизвестный факт и, естественно, после удаления элемента массива итератор должен быть получен заново
 

McSimm

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

можно после unset($a[$i]) выполнить $a = array_values($a);
или удалять с помощью array_splice($a, i, 1);

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

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

whirlwind

TDD infected, paranoid
Andreika ты адресом не ошибся?

zerkms
Это еще раз подтверждает, что массив в PHP это хэш. Я не знаю ни одного языка, в котором есть встроенный оператор удаления элемента массива. Потому что это слишком дорогостоящая в плане времени выполнения операция. Удаление элемента хэша гораздо дешевле в этом отношении, т.к. такие элементы не завязаны на порядке следования -> сдвигать элементы не нужно. А итератор я привел как пример невозможности использования foreach.
 

Andreika

"PHP for nubies" reader
whirlwind
да вроде не ошибся... с этого момента в пхп как и в перле можно удалять элемент массива
или может вы объясните что вы хотели показать общественности тем кодом?
 

whirlwind

TDD infected, paranoid
Andreika вопрос задавал не я. И вам следует перечитать этот вопрос еще раз, если непонятно что я хотел показать тем кодом. Раз вам так интересно, объясню почему это
с этого момента в пхп как и в перле можно удалять элемент массива
не верно.

Удаляется не элемент массива, в котором каждому элементу сопоставлен целочисленный номер, а элемент хеша, которому может быть сопоставлена произвольная строка. Индекс массива - это линейная последовательность. Индекс хеш-массива - дерево. В перле нет функции удаления элемента массива. Есть функция удаления элемента хеш-массива

PHP:
%hash = (1=>'a',2=>'b',3=>'c');
delete($hash{2});
в php вместо delete используется unset, но это по сути одно и то же. Для работы с массивами в перле есть несколько функций, позволяющих работать с вершиной и дном массива как со стеком shift, unshift, push, pop что имеем и в PHP. В перле насчет контекстов вообще все замечательно. Список приводится к хешу (главное что бы в нем было четное кол-во элементов), хеш к списку, при этом ключи становятся нечетными элементами, а значения четными. Но если уж привели к хешу, не обижайтесь, если обратная трансформация не даст исходного массива, т.к. обращение по ключу - это одно, а по индексу - это другое. Все логично и понятно. PHP аналоги работают не иначе как (в код не лазил, но перед глазами так и маячит NULL на индекс в массиве ключей при unset - что говорить, PHP оригинальностью не блистает) на основе индексов по array_keys, т.к. PHP массив сохраняет порядок задания элементов. В перле порядок следования неопределен, т.е. keys(%hash) не обязательно вернет список ключей в порядке их задания. Кроме путаницы (в хеше нельзя полагаться на порядок задания, а удаление элемента массива влечет за собой смещение вышестоящих элементов) один плюс - порядок следования элементов не изменяется. Если сможете привести пример ЯП, где к массивам такое же отношение как и в PHP, будет замечательно. Однако уверен, что таких примеров будет не много. И ничего удивительного, что у программистов владеющих другими ЯП, могут возникнуть трудности при работе с массивами в PHP.
 

Andreika

"PHP for nubies" reader
whirlwind
вы показали код, я его не понял и до сих пор не понимаю..

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

если тем примером пытался объяснить, что
@a = (1,2,10);
delete(@a(1)); == (0=>1,1=>10), то пример ну крайне неудачный был... да, действительно в перле будет так?

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

Если сможете привести пример ЯП, где к массивам такое же отношение как и в PHP, будет замечательно
да я вообще-то больше языков с родными ассоциативными массивами вспомнить не могу :( а в отстальных... ну допустим удалить 11ый элемент array[0..22] of Char или byte [20] немного тяжелее, чем в перле
 

whirlwind

TDD infected, paranoid
Пойдем сначала

Автор оригинала: zerkms
а критерий "нормальности" массива где можно посмотреть? и в каком собственно ЯП после удаления элемента массива магическим образом остальные будут сдвинуты?
Приведенный код был примером ЯП в котором происходит сдвиг вышестоящих элементов.

сначала давайте выползем на "пользовательский" уровень, в котором array называется массивом
Массивы бывают 2х видов: ассоциативный массив и индексный массив. Они принципиально различны (но для программистов на PHP это из разряда тайн что ли?) В перле эти два типа различаются. Для спискового (индексный массив) контекста используется префикс @, для хеша (ассоциативный массив) используется префикс %.

@a = (1,2,10);
delete(@a(1)); == (0=>1,1=>10), то пример ну крайне неудачный был... да, действительно в перле будет так?
Нет не будет. Во первых там был не delete, а shift. delete в перле применимо только к ассоциативным массивам, но не к индексным. Для удаления серединных элементов массивов функции нет. Есть функции для получения среза массива, но это уже манипуляция массивами, а не его элементами.

Удаление первых и последних элементов массива может быть выполнено без физического перемещения. Например, при удалении элементов сначала сохраняем индекс первого значимого элемента (тот, который был перед удаленным). При обращении по индексу из запрашиваемого индекса просто вычитается это значение. С концом массива - аналогично с небольшими частностями. Все это реализуется ЯП и программисту об этом знать не нужно.

да я вообще-то больше языков с родными ассоциативными массивами вспомнить не могу

надо просто запомнить, что числовой индекс ничем не отличается в этом плане от строки и все
Изначально были только индексные массивы. В большинстве языков в той или иной мере реализован механизм работы с массивами. По крайней мере это поддержка синтаксиса доступа к элементам массива на основе целочисленных индексов. Уже после появились ассоциативные массивы. Вероятнее всего, ассоциативность PHP массивов - это просто надстройка над индексным массивом. Учитывая что индексные массивы являются привычными и естественными для программистов на абсолютно различных ЯП, трудно назвать поведение "ассоциативного" массива PHP логичным

-- мы работаем с индексным массивом, почему в нашем массиве появилась дырка после удаления элемента?

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

Andreika

"PHP for nubies" reader
Приведенный код был примером ЯП в котором происходит сдвиг вышестоящих элементов.
извините, извините... а что он доказывает?

Нет не будет. Во первых там был не delete, а shift.
дык в том то и дело, что там был shift
то, что в перле любой массив таким образом можно сдвинуть? ну дык и в php с этим все аналогично

PHP:
$arr = array(1,2,10);
echo $arr[0]." ".$arr[1]."\n";
array_shift($arr);
echo $arr[0]." ".$arr[1]."\n";
1 2
2 10

трудно назвать поведение "ассоциативного" массива PHP логичным
опять же почему? для индексных массиовов, как вы упомянули - unset($arr[2]) - грязный хак по сути.. не понимаешь - не пользуйся (есть куча полезных функций, с которыми приятно и комфортно) и будет тебе обычный индексный массив (хотя не факт..) - разница ну вообще не заметна
 

StUV

Rotaredom
whirlwind
я про это:
Вероятнее всего, ассоциативность PHP массивов - это просто надстройка над индексным массивом. Учитывая что индексные массивы являются привычными и естественными для программистов на абсолютно различных ЯП, трудно назвать поведение "ассоциативного" массива PHP логичным
на самом деле в мане все просто и ясно написано - поэтому не надо вводить людей в заблуждение отстраненными теоретизированиями

т.е. для "непродвинутого" пользователя не важно, как это реализовано - важно, как этим пользоваться

зы: а топик читал весь - действительно, очень смешно =)
 
Сверху