как остановить фильтр от продолжения набора записей или коллекции - PullRequest
1 голос
/ 22 февраля 2012

Итак, у меня есть переменная и набор записей:

$firstRecordID = 1;
$records = Recordset::all();

Я хочу отфильтровать набор записей:

$filteredRecords = $records->find(function($record) use ($firstRecordID){
    return ($record->id == $firstRecordID);
});

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

Мой вопрос: как заставить фильтр останавливаться после выполнения определенного условия?

edit: я добавлю еще один более сложный пример:

$filteredRecords = $records->find(function($record) use ($lastRecordID){
    $conditions == $records->conditions;
    // in here I would find some value 
    // based on some other unknown record based on the $conditions

    // if the value matches any of the $conditions return the row
    // if the value matches a specified stop condition 
    // (which is defined by the user) stop retrieving rows.
});

Ответы [ 2 ]

0 голосов
/ 24 февраля 2012

Краткий ответ

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

Длинный ответ

Вы слишком сосредоточены на конкретной тактике (остановка find при использовании фильтра), когда вам может быть полезно отступить назад и подумать, чего вы пытаетесь достичь.

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

Дело в том, что передача функции фильтра в find уже настолько неэффективна, насколько вы можете ее получить, потому что li3 придется извлечь каждую запись из базы данных , прежде чем ваш фильтр даже будет вызван. Вот где неэффективность. Остановка процесса фильтрации, когда вы нажмете 10 предметов или что-то еще, не будет иметь большого значения (если ваша фильтрация также не очень дорогая).

Я бы порекомендовал подумать о следующем:

  1. Вам действительно нужно разрешить какой-либо метод фильтрации вообще? Можно ли использовать декларативные условия? Если это так, вы можете указать опции limit и позволить базе данных выполнять всю работу.

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

0 голосов
/ 22 февраля 2012

Я думаю, что решение состоит в том, чтобы использовать сначала ($ filter)

$filteredRecords = $records->first(function($record) use ($firstRecordID){
    return ($record->id == $firstRecordID);
});

http://li3.me/docs/lithium/util/Collection::first

...