Какой самый эффективный способ выбрать каждый n-й элемент из большого массива? Есть ли «умный» способ сделать это или зацикливать единственный способ?
Некоторые моменты, которые следует учитывать:
for($i = 0; $i <= 130000; $i += 205)
не будет работать До сих пор это самый эффективный метод, который я придумал:
$result = array(); $i = 0; foreach($source as $value) { if($i >= 205) { $i = 0; } if($i == 0) { $result[] = $value; } $i++; }
Или же с модулем:
$result = array(); $i = 0; foreach($source as $value) { if($i % 205 == 0) { $result[] = $value; } $i++; }
Эти методы могут быть довольно медленными, есть ли способ улучшить? Или я просто расщепляю волосы здесь?
РЕДАКТИРОВАТЬ
Хорошие ответы вокруг с правильными объяснениями, попытались выбрать наиболее подходящий, как принятый ответ. Благодаря!
Цикл foreach обеспечивает самую быструю итерацию по вашему большому массиву на основе тестирования сравнения. Я бы придерживался чего-то похожего на то, что у вас есть, если кто-то не хочет решить проблему с разворачиванием цикла .
Этот ответ должен выполняться быстрее.
$result = array(); $i = 0; foreach($source as $value) { if ($i++ % 205 == 0) { $result[] = $value; } }
У меня нет времени на тестирование, но вы можете использовать вариацию решения @ haim, если вы сначала индексируете массив массивом. Стоит посмотреть, сможете ли вы получить прибыль от моего предыдущего решения:
$result = array(); $source = array_values($source); $count = count($source); for($i = 0; $i < $count; $i += 205) { $result[] = $source[$i]; }
Это во многом будет зависеть от того, насколько оптимизирована функция array_values. Это может очень хорошо выполнить ужасно.
Попробуйте ArrayIterator :: seek ()
Кроме того, использование одной новой структуры данных Spl может привести к лучшим результатам, чем использование простых массивов.
Я рекомендую использовать array_slice
$count = count($array) ; for($i=205;$i<$count;$i+=205){ $result[] = array_slice($array,$i,1); }
Если ваш массив был численно проиндексирован, это было бы очень быстро:
$count = count($array) ; for($i=205;$i<$count;$i+=205){ $result[] = $array[$i]; }
Я думаю, что решение этой проблемы не связано ни с одним синтаксисом PHP, а с дизайном вашего кода.
Вы можете либо сделать числовое индексирование массива (возможно, не правдоподобным для вашего приложения), отслеживать каждый 205-й элемент или только один раз искать массив (кешировать список каждого 205-го элемента).
На мой взгляд, отслеживание каждого 205-го элемента было бы проще реализовать. Вы просто сохраните счет всех элементов в базе данных или что-то еще, и каждый раз, когда элемент добавляется, проверьте по модулю счет. Если у вас есть еще 205-й элемент, добавьте его в массив. Ибо, когда элементы удаляются, это было бы сложнее. Возможно, вам придется перепроверить весь массив, чтобы перестроить все ваши 205-е позиции.
Выполнение этого было бы проще, если бы вы могли начать работу с удаленным элементом и двигаться вперед, но опять же это будет работать только для массивов с числовой индексацией – и если бы это было так, вам не пришлось бы двигаться вперед вообще, вы просто сделали бы немного математики, чтобы пересмотреть его.
Если это действительно является узким местом, вы можете подумать над переосмыслением своего дизайна, чтобы сделать его численно проиндексированным.
EDIT: создайте и сохраните отдельный массив с 205-ю элементами (которые обновляются вставляются или что-то в этом роде).
Может показаться глупым, но по определению это быстрее, поскольку вы напрямую обращаетесь к ячейкам памяти и не выполняете никаких сравнений.
Кажется, вы не можете перемещать указатель массива более одного раза за раз. Я лично использовал бы это:
reset($source); $next = true; while($next === true){ $result[] = current($source); for(i=0;i<205;i++){ $next = next($source); } }
Если кто-то может найти функцию, которая может перемещать указатель массива более чем на один шаг за раз, у вас будет лучший ответ. Я думаю, что это хорошо.
Вы можете использовать array_keys
для работы только с ключами массива.
$keys = array_keys($array); for ($i=0, $n=min(count($keys), 130000); $i<$n; $i += 205) { $result[] = $array[$keys[$i]]; }