Каков был бы самый эффективный способ выбрать каждый энный объект из большого массива? Существует ли 'умный' способ сделать, это или действительно ли цикличное выполнение - единственный путь?
Некоторые вопросы для рассмотрения:
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];
}
Если это действительно узкое место, вы можете подумать о переосмыслении вашего дизайна, чтобы сделать его числовым индексом .
РЕДАКТИРОВАТЬ: Или создайте и поддерживайте отдельный массив только с 205-ю элементами (который обновляется при вставке или что-то подобное).
Вы можете ' t перемещать указатель массива, кажется, более одного раза за раз. Я бы лично использовал это:
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]];
}
Я думаю, что решение этой проблемы лежит не в синтаксисе PHP, а в дизайне вашего кода.
Вы можете либо сделать массив числовым (может быть неправдоподобным для вашего приложения), либо отслеживать каждый 205-й элемент, либо искать в массиве только один раз (кэшировать список каждого 205-го элемента).
На мой взгляд, отслеживать каждый 205-й элемент было бы проще. Вы просто будете вести подсчет всех элементов в базе данных или что-то в этом роде, и каждый раз, когда элемент добавляется, проверять модуло подсчета. Если у вас есть еще один 205-й элемент, добавьте его в массив. Ведь когда элементы удаляются, это будет более хитро. Возможно, вам придется перепроверить весь массив, чтобы перестроить все 205-е элементы.
Это было бы проще, если бы вы могли начать с удаленного элемента и двигаться вперед, но опять же это работало бы только для численно проиндексированных массивов - и если бы это было так, вам вообще не пришлось бы двигаться вперед, вы бы просто сделали небольшие математические расчеты, чтобы перестроить его.