Фильтровать ArrayObject (PHP)

У меня есть данные в ArrayObject, просто представляющие массив. Мне нужно отфильтровать данные, функция array_filter() прекрасно сработает. Однако он не работает с ArrayObject в качестве аргумента. Как лучше с этим лечиться? Есть ли стандартная функция, которая обрабатывает фильтрацию для меня?

Пример:

$my_data = ArrayObject(array(1,2,3));
$result = array_object_filter($my_data, function($item) { return $item !== 2; });

Есть ли функция array_object_filter?


person Pavel S.    schedule 30.06.2012    source источник
comment
Вы не можете использовать цикл foreach?   -  person Mark Eirich    schedule 30.06.2012
comment
Да, я могу. Но мне это кажется немного некрасивым. Я знаю несколько подходов к решению этой проблемы, но я хотел бы услышать лучший из них. Ничто из того, что я знаю, не является действительно чистым.   -  person Pavel S.    schedule 30.06.2012
comment
Что вы подразумеваете под чистым? Вам не кажется, что array_filter() использует внутренний цикл?   -  person Mark Eirich    schedule 30.06.2012
comment
Да, внутренне. Это то, что я считаю чистой стандартной библиотечной функцией.   -  person Pavel S.    schedule 30.06.2012
comment
Просто нет встроенной функции PHP для выполнения того, что вы просите. См. список функций на странице php.net/arrayobject — это все, что есть. PHP никогда не будет делать все за вас.   -  person Mark Eirich    schedule 30.06.2012


Ответы (3)


Как насчет того, чтобы экспортировать его в настоящий массив, а затем создать новый объект массива?

$my_data = new ArrayObject(array(1,2,3));
$result = new ArrayObject( 
    array_filter( (array) $my_data, function($item) { 
         return $item !== 2; 
    })
);
person Berry Langerak    schedule 30.06.2012
comment
Я сделал это, но это кажется некрасивым для меня. Есть ли что-нибудь красивее? Поскольку это объект, я могу расширить его и добавить к нему метод фильтра... Но в стандартной библиотеке действительно ничего нет? - person Pavel S.; 30.06.2012
comment
@ПавелС. Во всяком случае, не то, что я знаю. Очевидно, вы действительно можете расширить ArrayObject до FilterableArrayObject, который принимает анонимную функцию и обеспечивает фильтрацию. Это, вероятно, самое чистое решение, хотя я бы сказал, что при фильтрации вы все равно получите другой экземпляр ArrayObject, поэтому это решение кажется оптимальным. - person Berry Langerak; 30.06.2012

Как насчет подкласса ArrayObject и добавления к нему нового метода:

/**
 * Filters elements using a callback function.
 *
 * @param callable $callback The callback function to use
 *
 * @return self
 */
public function filter(/* callable */ $callback = null)
{
    $this->exchangeArray(array_filter($this->getArrayCopy(), $callback));
    return $this;
}
person Rico Sonntag    schedule 29.03.2017
comment
отлично! именно то, что я собирался сделать, если бы не нашел это - person Lachezar Raychev; 30.05.2021

Как насчет этого:

$my_data = new ArrayObject(array(1,2,3));
$callback = function($item) { return $item !== 2; };
$result = new ArrayObject;
foreach ($my_data as $k => $item) if ($callback($item)) $result[$k] = $item;

Кроме того, вы можете сами определить функцию array_object_filter():

function array_object_filter($array, $callback) {
    $result = new ArrayObject;
    foreach ($array as $k => $item) if ($callback($item)) $result[$k] = $item;
    return $result;
}
person Mark Eirich    schedule 30.06.2012