php сбросить индексы массива

reset

(PHP 4, PHP 5, PHP 7, PHP 8)

reset — Устанавливает внутренний указатель массива на его первый элемент

Описание

reset() перемещает внутренний указатель массива array к его первому элементу и возвращает значение первого элемента массива.

Список параметров

Возвращаемые значения

Примеры

Пример #1 Пример использования reset()

Примечания

Смотрите также

User Contributed Notes 13 notes

GOTCHA: If your first element is false, you don’t know whether it was empty or not.

?>

So don’t count on a false return being an empty array.

As for taking first key of an array, it’s much more efficient to RESET and then KEY, rather then RESET result of ARRAY_KEYS (as sugested by gardnerjohng at gmail dot com).

Also it’s good to reset this way the multidimentional arrays:

Note that reset() will not affect sub-arrays of multidimensional array.

In response to gardnerjohng’s note to retrieve the first _key_ of an array:

To retrieve the first _key_ of an array you can use the combination of reset() and key().

Since reset() returns the first «value» of the array beside resetting its internal pointer; it will return different results when it is combined with key() or used separately. Like;

?>

This is perfectly normal because in the first method, reset() returned the first «value» of the ‘biscuits’ element which is to be «cbosi». So key(string) will cause a fatal error. While in the second method you just reset the array and didn’t use a returning value; instead you reset the pointer and than extracted the first key of an array.

If your array has more dimensions, it won’t probably cause a fatal error but you will get different results when you combine reset() and key() or use them consecutively.

Following code gives a strict warning in 5.4.45

«Strict warning: Only variables should be passed by reference»

$keys = array_keys($result[‘node’]);
return reset($keys);

I had a problem with PHP 5.0.5 somehow resetting a sub-array of an array with no apparent reason. The problem was in doing a foreach() on the parent array PHP was making a copy of the subarrays and in doing so it was resetting the internal pointers of the original array.

The following code demonstrates the resetting of a subarray:

Unfortunately for me, my key required to be more than just a simple string or number (if it was then it could be used to directly index the subarray of data for that object and problem avoided) but was an array of strings. Instead, I had to iterate over (with a foreach loop) each subarray and compare the key to a variable stored within the subarray.

So by using a foreach loop in this manner and with PHP resetting the pointer of subarrays it ended up causing an infinite loop.

Really, this could be solved by PHP maintaining internal pointers on arrays even after copying.

Источник

Как вы переиндексировать массив в PHP?

У меня есть следующий массив, который я хотел бы переиндексировать, чтобы ключи поменялись местами (в идеале, начиная с 1):

Текущий массив (редактировать: массив на самом деле выглядит так):

Как это должно быть:

Решение

Если вы хотите переиндексировать, начиная с нуля, просто сделайте следующее:

Если вам нужно, чтобы начать с одного, то используйте следующее:

Вот справочные страницы для используемых функций:

Другие решения

Вот лучший способ:

объяснение

array_values() Возвращает значения входного массива и численно индексирует.

array_filter() : Фильтрует элементы массива с помощью пользовательской функции (UDF Если ничего не предоставлено, все записи во входной таблице со значением FALSE будут удалены.)

Почему переиндексация? Просто добавьте 1 к индексу:

редактировать После выяснения вопроса: вы можете использовать array_values сбросить индекс, начиная с 0. Тогда вы можете использовать алгоритм, приведенный выше, если вы просто хотите, чтобы напечатанные элементы начинались с 1.

Я только что узнал, что вы также можете сделать

Это делает переиндексацию на месте, поэтому вы не получите копию исходного массива.

Что ж, я хотел бы думать, что для любой вашей конечной цели вам на самом деле не нужно изменять массив, чтобы он был основан на 1, а не на 0, но вместо этого мог бы обрабатывать его во время итерации, как написал Гамбо.

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

РЕДАКТИРОВАТЬ

Вот более многоразовая / гибкая функция, если хотите

Это будет делать то, что вы хотите:

Более элегантное решение:

Вы можете переиндексировать массив, чтобы новый массив начинался с индекса 1 следующим образом;

Источник

Сбросить ключи элементов массива с помощью PHP?

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

Использование функции key_swap (): эта функция будет вводить массив и две клавиши, а затем менять значения, соответствующие этим двум клавишам, с помощью другой переменной ($ val) и возвращать полученный массив.

Примечание. Эта функция выдаст ошибку, если оба ключа отсутствуют в массиве.

Использование функции key_change (): эта функция будет вводить массив и два ключа, один старый ключ (уже присутствующий в массиве) и новый ключ. Функция сначала сохранит значение, соответствующее старому ключу, в третьей переменной ($ val), а затем удалит (unset ()) старый ключ и соответствующее ему значение из массива. Затем новый ключ будет добавлен в массив, ему будет присвоено значение, хранящееся в третьей переменной ($ val), и полученный массив будет возвращен.

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

Программа: PHP-программа для сброса ключей элемента массива в массиве.

// PHP-программа для сброса ключей элементов массива

// Функция для обмена значениями любого
// два ключа в массиве

// Функция для изменения ключа, соответствующего
// к значению в массиве

// Пример ассоциативного массива

$arr = array ( ‘zero’ => 1,

// Распечатать массив образцов

echo «The Sample array: » ;

// Меняем местами клавиши «ноль» и «один»

// Меняем местами клавиши «ноль» и «два»

// Меняем ключ ‘test’ на ‘three’

Источник

array_values

(PHP 4, PHP 5, PHP 7, PHP 8)

array_values — Выбирает все значения массива

Описание

Список параметров

Возвращаемые значения

Возвращает индексированный массив значений.

Примеры

Пример #1 Пример использования array_values()

Результат выполнения данного примера:

Смотрите также

User Contributed Notes 25 notes

Remember, array_values() will ignore your beautiful numeric indexes, it will renumber them according tho the ‘foreach’ ordering:

Just a warning that re-indexing an array by array_values() may cause you to reach the memory limit unexpectly.

Doing this will cause PHP exceeds the momory limits:

Most of the array_flatten functions don’t allow preservation of keys. Mine allows preserve, don’t preserve, and preserve only strings (default).

echo ‘var_dump($array);’.»\n»;
var_dump($array);
echo ‘var_dump(array_flatten($array, 0));’.»\n»;
var_dump(array_flatten($array, 0));
echo ‘var_dump(array_flatten($array, 1));’.»\n»;
var_dump(array_flatten($array, 1));
echo ‘var_dump(array_flatten($array, 2));’.»\n»;
var_dump(array_flatten($array, 2));
?>

If you are looking for a way to count the total number of times a specific value appears in array, use this function:

I needed a function that recursively went into each level of the array to order (only the indexed) arrays. and NOT flatten the whole thing.

Remember, that the following way of fetching data from a mySql-Table will do exactly the thing as carl described before: An array, which data may be accessed both by numerical and DB-ID-based Indexes:

/*
fruit1 = apple
fruit2 = orange
fruit5 = apple
*/
?>

A comment on array_merge mentioned that array_splice is faster than array_merge for inserting values. This may be the case, but if your goal is instead to reindex a numeric array, array_values() is the function of choice. Performing the following functions in a 100,000-iteration loop gave me the following times: ($b is a 3-element array)

array_splice($b, count($b)) => 0.410652
$b = array_splice($b, 0) => 0.272513
array_splice($b, 3) => 0.26529
$b = array_merge($b) => 0.233582
$b = array_values($b) => 0.151298

same array_flatten function, compressed and preserving keys.

/**********************************************
*
* PURPOSE: Flatten a deep multidimensional array into a list of its
* scalar values
*
* array array_values_recursive (array array)
*
* WARNING: Array keys will be lost
*
*********************************************/

Non-recursive simplest array_flatten.

A modification of wellandpower at hotmail.com’s function to perform array_values recursively. This version will only re-index numeric keys, leaving associative array indexes alone.

Please note that ‘wellandpower at hotmail.com’s recursive merge doesn’t work. Here’s the fixed version:

The function here flatterns an entire array and was not the behaviour I expected from a function of this name.

I expected the function to flattern every sub array so that all the values were aligned and it would return an array with the same dimensions as the imput array, but as per array_values() adjusting the keys rater than removing them.

In order to do this, you will want this function:

function array_values_recursive($array) <
$temp = array();

Hopefully this will assist.

Note that in a multidimensional array, each element may be identified by a _sequence_ of keys, i.e. the keys that lead towards that element. Thus «preserving keys» may have different interpretations. Ivan’s function for example creates a two-dimensional array preserving the last two keys. Other functions below create a one-dimensional array preserving the last key. For completeness, I will add a function that merges the key sequence by a given separator and a function that preserves the last n keys, where n is arbitrary.

/*
* Flattening a multi-dimensional array into a
* single-dimensional one. The resulting keys are a
* string-separated list of the original keys:
*
* a[x][y][z] becomes a[implode(sep, array(x,y,z))]
*/

Источник

Работа с памятью (и всё же она есть)

php сбросить индексы массива. Смотреть фото php сбросить индексы массива. Смотреть картинку php сбросить индексы массива. Картинка про php сбросить индексы массива. Фото php сбросить индексы массиваСуществует распространенное мнение, что «рядовому» PHP разработчику практически не нужно заботиться об управлении памятью, однако «заботиться» и «знать» всё же немного разные понятия. Попытаюсь осветить некоторые аспекты управлению памятью при работе с переменными и массивами, а также интересные «подводные камни» внутренней оптимизации PHP. Как вы сможете убедиться, оптимизация это хорошо, но если не знать как именно она «оптимизирует», то можно столкнуться с «неочевидными граблями», которые могут вас заставить изрядно понервничать.

Общие сведения

Небольшой ликбез

Переменная в PHP как бы состоит из двух частей: «имени«, которое хранится в hash_table symbol_table, и «значения«, которое хранится в zval контейнере.
Такой механизм позволяет создавать несколько переменных ссылающихся на одно значение, что в отдельных случаях позволяет оптимизировать потребление памяти. О том, как это выглядит на практике будет написано далее.

Наиболее частыми элементами кода, без которых сложно себе представить более менее функциональный скрипт, являются следующие моменты:
— создание, присвоение и удаление переменных (чисел, строк и т.п.),
— создание массивов и их обход (в качестве примера будет использована функция foreach),
— передача и возврат значений для функций/методов.

Именно об этих аспектах работы с памятью и будет последующее описание. Получилось достаточно объемно, но ничего мега-сложного не будет и всё будет достаточно просто, очевидно и с примерами.

Первый пример работы с памятью

И простой первый пример теста потребления памяти для строки:

include ( ‘func.php’ ) ;
echo «String memory usage test.\n\n» ;
$base_memory_usage = memory_get_usage ( ) ;
$base_memory_usage = memory_get_usage ( ) ;

Примечание: несомненно код является неоптимизированным с точки зрения работоспособности, но в данном случае нам исключительно важна наглядность потребления памяти, для которой и реализовано данное представление.

Результат кода вполне очевиден:

Start
Bytes diff: 0
String value setted
Bytes diff: 15448
String value unsetted
Bytes diff: 0

Тот же самый пример, но вместо unset($a) используем $a=null;:

Start
Bytes diff: 0
String value setted
Bytes diff: 15448
String value set to null
Bytes diff: 76

Как видите, переменная не была полностью уничтожена. Под нее остается выделенным еще 76 байт.
Достаточно прилично, если учесть, что ровно столько же выделяется и под переменные типа boolean, integer, float. Речь идет не об объеме памяти, выделяемой под значение переменной, а о полном потреблении памяти для хранения сведений о присвоенной переменной (zval контейнер со значением и само имя переменной).
Так что если вы хотите освободить память при помощи присвоения, то не является принципиальным присвоение именно null значения. Выражение $a=10000; даст тот же результат для расхода памяти.

В документации PHP сказано, что приведение к null уничтожит переменную и ее значение, однако, по данному скрипту видно что это не так, что собственно является багом (документации).

Зачем использовать присвоение null, если можно unset()?
Присвоение — это присвоение, (спасибо КО), то есть изменяется значение переменной, соответственно, если новое значение требует меньше памяти, то она высвобождается сразу, однако это требует вычислительных ресурсов (пусть и сравнительно немного).
unset() в свою очередь освобождает память, выделенную под имя переменной и ее значение.
Отдельно стоит упомянуть момент, что unset() и присвоение null совершенно по разному работают со ссылками на переменные. Unset() уничтожит только ссылку, в то время как присвоение null изменит значение, на которое ссылаются имена переменных, соответственно все переменные станут ссылаться на значение null.

Примечание:
Встречается заблуждение, что unset() является функцией, однако, это не верно. unset() — это языковая конструкция (как например if), о чем прямо сказано в документации, соответственно ее нельзя использовать для обращения через значение переменной:

Немного дополнительной информации для праздных размышлений (при изменении примера выше):
$a = array();
выделит 164 байта, unset($a) всё вернет.

class A < >
$a = new A();
выделит 184 байта, unset($a) всё вернет.

$a = new stdClass();
выделит 272 байта, но после unset($a) «утекут» 88 байт (куда именно и почему они утекли, мне пока не удалось выяснить).

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

Массивы

Массивы в PHP «съедают» достаточно памяти, и именно в них как правило хранят значительные объемы данных при обработке, поэтому следует очень аккуратно относиться к работе с ними. Однако, работа с массивами в PHP имеет свои «прелести оптимизации» и об одном из таких моментов, связанных с потреблением памяти, стоит упомянуть.

? php
include ( ‘func.php’ ) ;
echo «Array memory usage example.» ;
$base_memory_usage = memory_get_usage ( ) ;
$base_memory_usage = memory_get_usage ( ) ;

Посмотрите на вывод:

Array memory usage example.Base usage.
Bytes diff: 0
Array is set.
Bytes diff: 61940
In FOREACH cycle.
Bytes diff: 77632
In FOREACH cycle.
Bytes diff: 93032
In FOREACH cycle.
Bytes diff: 108432
In FOREACH cycle.
Bytes diff: 123832
Usage right after FOREACH.
Bytes diff: 61940
Array unset.
Bytes diff: 0

Получается, что в последней итерации цикла foreach в данном случае потребление массивом памяти возросло в два раза, хотя по самому коду это не очевидно. Но сразу после цикла, потребление памяти вернулось к прежнему значению. Чудеса да и только.
Причиной тому является оптимизация использования массива в цикле. На время работы цикла, при попытке изменить исходный массив, неявно создается копия структуры массива (но не копия значений), которая и становится доступной по завершению цикла, а исходная структура уничтожается. Таким образом, в вышеприведенном примере, если вы присваиваете новые значения исходному массиву, то они не будут заменены сразу, а для них будет выделена отдельная память, которая будет возвращена по выходу из цикла.
Этот момент очень легко пропустить, что может привести к значительному потреблению памяти на время работы цикла с большими массивами данных, например при выборке из БД.

Дополнение от пользователя zibada (в кратце):
Важно учесть, что выделение памяти под новый «временный массив» в случае внесения изменений, произойдет единовременно для всей структуры массива, но отдельно для каждого изменяемого элемента. Таким образом, если имеется массив с большим количеством элементов, (но не обязательно с большими значениями), то единовременное потребление памяти при таком копировании будет существенно.

Коварный пример №2
Чуть-чуть изменим код.

Сам код цикла мы никак не меняли, единственное что мы изменили, это увеличили счетчик ссылок на исходный массив, но это в корне поменяло работу цикла:

Bytes diff: 0
Array is set.
Bytes diff: 61940
In FOREACH cycle.
Bytes diff: 61988
In FOREACH cycle.
Bytes diff: 61988
In FOREACH cycle.
Bytes diff: 61988
In FOREACH cycle.
Bytes diff: 61988
Usage right after FOREACH.
Bytes diff: 61940
Array unset.
Bytes diff: 0

Bytes diff: 0
Array is set.
Bytes diff: 61940
In FOREACH cycle.
Bytes diff: 61940
In FOREACH cycle.
Bytes diff: 61940
In FOREACH cycle.
Bytes diff: 61940
In FOREACH cycle.
Bytes diff: 61940
Usage right after FOREACH.
Bytes diff: 61940
Array unset.
Bytes diff: 0

Передача по ссылке или передача через копирование

Рассмотрим случай, «что делать» если требуется передать в метод или функцию (или вернуть из них), какое-либо очень большое значение. Первым очевидным решением обычно рассматривают использование передачи/возвращения по ссылке.
Однако в документации по PHP сказано: Не используйте возврат по ссылке для увеличения производительности. Ядро PHP само занимается оптимизацией.
Попытаемся разобраться в том, что же это за «оптимизация».

Для начала самый простой пример (пока без передачи аргументов):

Start
Bytes diff: 0
String value setted
Bytes diff: 15496
String value unsetted
Bytes diff: 0

В результате получим вывод:

Bytes diff: 0
String value setted
Bytes diff: 30896
String value unsetted
Bytes diff: 0

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

Данный пример даст выход:

Bytes diff: 0
String value setted
Bytes diff: 46704
String value unsetted
Bytes diff: 0

Всё выше описанное действует аналогично и для передачи/возврата значений через «оптимизированное копирование» внутрь/из функций и методов. Если внутри метода вы никак не «трогаете» переданное значение, то для него не будет выделена отдельная область памяти (память будет выделена только под имя переменной, чтобы связать ее со значением). Если же вы передаете «через копирование» и изменяете значение внутри метода, то перед попыткой сделать изменение уже будет создана действительная полная копия значения.

Таким образом PHP действительно избавляет от необходимости использовать передачу по ссылке для оптимизации использования памяти. Передача по ссылке имеет практическое значение только если исходное значение требуется изменить с отображением этих изменений извне метода.

echo «Array memory usage example.» ;
$base_memory_usage = memory_get_usage ( ) ;
$base_memory_usage = memory_get_usage ( ) ;

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

Исключительно в познавательных целях, стоит обратить внимание на эти два значения:

Примечание:
В PHP5 (в отличие от PHP4), все объекты по-умолчанию передаются по ссылке, хотя по факту, это неполноценная ссылка. См. эту статью.

Краткие выводы

Несомненно приведенные примеры оптимизации использования памяти в PHP лишь «капля в море», однако они описывают самые частые случаи, когда имеет смысл задуматься о том, какой код выбрать чтобы оптимизировать расход памяти и избавить себя от лишней головной боли.

Отдельно стоило бы затронуть механизм расходования и оптимизации памяти при использовании объектов, однако ввиду обилия возможных примеров этот момент требует отдельной статьи. Возможно когда-нибудь.

PS: Можно было бы разбить это на несколько статей, но не вижу в этом смысла, так как подобную информацию лучше всё же хранить «вместе». Полагаю тем, кому данная информация несет практический смысл, так будет удобнее. Тестировалось на PHP 5.3.2 (Ubuntu 32bit), так что ваши значения по выделенным байтам могут отличаться.

UPD
В основной части статьи не был освещен важный момент.
Если есть переменная на которую создана ссылка, то при ее передаче в функцию в качестве аргумента она будет скопирована сразу, то есть не будет применена copy-on-write оптимизация.
Пример:

Источник

Добавить комментарий

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