Сбор значений столбцов в массив

Один из шаблонов, с которыми я часто сталкиваюсь при разработке, пытается собрать значение столбца / атрибута из коллекции объектов в массив. Например:

$ids = array(); foreach ($documents as $document) { $ids[] = $document->name; } 

Я единственный, кто сталкивается с этим? И есть ли у PHP способ решить это в меньшем количестве строк? Я посмотрел, но ничего не нашел.

Поскольку я использую структуру MVC, у меня есть доступ к классу BaseUtil, который содержит общие функции, которые действительно не подходят ни в каких конкретных классах. Одним из решений, предложенным сотрудником, является:

 class BaseUtil { public static function collect($collection, $property) { $values = array(); foreach ($collection as $item) { $values[] = $item->{$property}; } return $values; } } 

Тогда я могу просто сделать:

 $ids = BaseUtil::collect($documents, 'name'); 

Не слишком потертый. У кого-нибудь есть другие идеи? И я схожу с ума или это похоже на проблему, которую PHP должен был решить давно?

Вы можете использовать функцию array_map () для этой цели:

 function getName($obj) { return $obj->name; } $documentsName = array_map("getName", $documents); 

Вы можете также рассмотреть функцию create_function () для лямбда-функций, если вы не хотите создавать функцию getName () в глобальном пространстве имен.

В PHP 5.3 вы можете даже сделать:

 $documentsName = array_map(function ($obj) { return $obj->name; }, $documents); 

Вы можете сделать это легко с uuzo goodies

 $names = array_map(Functions::extract()->name, $documents); 

или с массивами (из узе-лайтов)

 $names = Arrays::map($documents, Functions::extract()->name); 

Вы даже можете извлечь вложенные поля вызовов методов или доступа к массиву и т. Д .:

 $names = Arrays::map($documents, Functions::extract()->getAuthor()->roles[0]); 

Выезд: http://ouzo.readthedocs.org/ru/latest/utils/functions.html#extract

См. Также функциональное программирование с ouzo (я не могу опубликовать ссылку).

другой подход заключается в использовании «богатых» объектов массива, подобных тем, которые найдены на других языках

например

  class Ary extends ArrayObject { function pluck($key) { $a = array(); foreach($this as $sub) $a[] = $sub[$key]; return new self($a); } function join($delim = ',') { return implode($delim, (array) $this); } static function init($ary) { return new self($ary); } } echo Ary::init(array( array('foo', 'bar'), array('baz', 'quux') ))->pluck(1)->join(); 

Одной из слабых сторон PHP как языка является то, что это не очень выразительно.

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

Я придерживаюсь того, что у вас есть, но вот еще один подход только для этого.

 class BaseUtil { public static function collect($collection, $property) { array_walk( $collection, array( __CLASS__, 'reduceObject' ), $property ); return $collection; } public static function reduceObject( &$object, $index, $property ) { $object = $object->{$property}; } } 

Спасибо за введение, ребята. Думаю, я просто воспользуюсь решением моего коллеги:

 class BaseUtil { public static function collect($collection, $property) { $values = array(); foreach ($collection as $item) { $values[] = $item->{$property}; } return $values; } } 

Загрузка коллекции Magento и повторение цикла в этой коллекции, чтобы вы могли добавить нужные значения в массив, это неэффективно. Соответствующий способ сделать это – использовать метод getColumnValues ​​(). Этот метод даст вам массив значений, указав имя столбца.

Вот подходящий способ сделать это.

 $collection =Mage::getModel('your/object')->getCollection() ->addFieldToSelect('customer_id'); $yourArray = $collection->getColumnValues('customer_id'); 

Это даст вам массив со всеми выбранными вами значениями customer_id.