[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Эффективный способ сбросить ключи массива
Alchemist
Имеется большой ассоциативный массив. Задача: сбросить ключи, чтобы получился обычный номерной массив с индексами от 0 до (n - 1).

array_values() - не вариант. Эта функция не сбрасывает ключи, а создает новый массив, что на больших массивах приводит к ошибке памяти (Fatal error: Allowed memory size exhausted)

Я пробовал смотреть в сторону сортирующих функций, и usort() в принципе делает что надо, но на больших массивах n*log(n) итераций берет немало времени.

Может кто-то знает более эффективный способ ?
T1grOK
Есть подозрение, что делаете, что то не так, раз уж нужно обрабатывать такие большие массивы.

Можно воспользоваться array_keys(), если конечно под специфику задачи подходит.
Или просто обойти ассоциативный массив дополняя его данными с числовыми индексами, а ассоциативные удалять. В итоге получится расход по памяти O(1) и сложность алгоритма O(n).

_____________
Mysql, Postgresql, Redis, Memcached, Unit Testing, CI, Kohana, Yii, Phalcon, Zend Framework, Joomla, Open Cart, Ymaps, VK Api
redreem
echo 'Before create array: ' . memory_get_usage() . '<br>';

$arr = [];
for ($i=0;$i<=100000;$i++) {
$arr[$i.$i] = $i;
}

echo 'After array created: ' . memory_get_usage() . '<br>';
$i = 0;
foreach ($arr as $k => $v) {
$arr[$i++] = $v;
unset($arr[$k]);
}
echo 'After array changed: ' . memory_get_usage() . '<br>';
print_r($arr);
Invis1ble
redreem
foreach создает копию массива, не? надо мерить memory_get_peak_usage(true)



ТС, попробуй как-то так
for ($i = 0, $count = count($array); $i < $count; ++ $i) {
$array[] = current($array);
unset($array[key($array)]);
}


_____________

Профессиональная разработка на заказ

Я на GitHub | второй профиль

redreem
Invis1ble
ну да, никто не мешает вместо foreach заюзать each, просто возни чуть больше.
twin
Многие функции сбрасывают ключи. Вот вариант к примеру
print_r(array_chunk($arr, count($arr))[0]);

Как он с большими массивами поведет себя не знаю, не мерял. :)

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

Нужно уважать мнение оппонета. Ведь заблуждаться - его святое право.

Настаивал, настаиваю и буду настаивать на своем. На кедровых орешках.

user posted image
SlavaFr
Цитата (Alchemist @ 15.11.2016 - 05:21)
rray_values() - не вариант. Эта функция не сбрасывает ключи, а создает новый массив, что на больших массивах приводит к ошибке памяти (Fatal error: Allowed memory size exhausted)

[сарказм] купи больше памяти на компютер [/сарказм]
[серьёзно] Есть куча методов, которые избегают создания больших масивов. К этим методам исчисляются стриеам, итераторы и прочие метода благодаря которым считывают и обрабатывают данные частями. Проблему надо решать ещё до того, как ты создал огромный масив с ключами [/серьёзно]

_____________
↓↓↓↓↓↓↓↓↓↓
ответ может быть здесь
или в mysql_error();
Alchemist
1) Спасибо всем ответившим.

2) Да, я знаю что проблему надо решать еще до её появления. И искренне рад за вас, если у вас это всегда получается. Про остальные случаи есть прекрасный пост на Баше: http://bash.im/quote/441869

3) foreach и array_chunk() копируют массив

4) array_keys() решает проблему в случае небольшого, но "тяжелого" массива. В случае большого массива простыми парами int => int, берет столько же памяти сколько и array_values()

5) циклы работают (и прекрасно) со строковыми ключами, но в случае номерных ключей уничтожают до половины массива.
Пример для теста: [11 => 17, 8 => 20, 10 => 31, 4 => 44, 3 => 48, 2 => 56, 1 => 70] - массив отсортирован по значению, ключ - идентификатор в БД
sergeiss
Цитата (Alchemist @ 15.11.2016 - 09:21)
Имеется большой ассоциативный массив.

Так пока не понятно - откуда он взялся, этот массив?

_____________
* Хэлп по PHP
* Описалово по JavaScript
* Хэлп и СУБД для PostgreSQL

* Обучаю PHP, JS, вёрстке. Интерактивно и качественно. За разумные деньги.

* "накапливаю умение телепатии" (С) и "гуглю за ваш счет" (С)

user posted image
twin
Цитата (Alchemist @ 15.11.2016 - 14:59)
но в случае номерных ключей уничтожают до половины массива.

Ты про числовые ключи ничего не говорил. Ну попробуй немного изменить код от Invis1ble
for ($i = 0, $count = count($array); $i < $count; ++ $i) {
$total[] = array_shift($array);
}

или так, еще проще:
while ($val = array_shift($array)) {
$total[] = $val;
}


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

Нужно уважать мнение оппонета. Ведь заблуждаться - его святое право.

Настаивал, настаиваю и буду настаивать на своем. На кедровых орешках.

user posted image
Valick
Цитата (Alchemist @ 15.11.2016 - 17:59)
ключ - идентификатор в БД

если вы скажете, что массив получен из БД, то тут половину форума кондратий хватит, а кое кто начнёт заряжать ружьё деревянными пулями

_____________
Стимулятор ~yoomoney - 41001303250491
sergeiss
Цитата (Valick @ 15.11.2016 - 20:33)
кое кто начнёт заряжать ружьё деревянными пулями

А почему деревянными, а не серебрянными? wink.gif

_____________
* Хэлп по PHP
* Описалово по JavaScript
* Хэлп и СУБД для PostgreSQL

* Обучаю PHP, JS, вёрстке. Интерактивно и качественно. За разумные деньги.

* "накапливаю умение телепатии" (С) и "гуглю за ваш счет" (С)

user posted image
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2024 Invision Power Services, Inc.