2009-11-03 56 views
8

开发时经常运行的模式之一是试图从对象集合中收集列/属性值到数组中。例如:将列值收集到数组中

$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应该解决的问题?

回答

10

可以使用array_map()功能用于此目的:

function getName($obj) { 
    return $obj->name; 
} 

$documentsName = array_map("getName", $documents); 

你也可以考虑在create_function()功能lambda函数,如果你不” t要在全局命名空间中创建一个getName()函数。

PHP 5.3你甚至可以这样做:

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

这对我的目的不起作用,因为我想将此概括为任何属性/属性;不只是名称。当试图做array_map()变得更加混乱,我不能得到它的工作。 – 2009-11-06 21:32:50

+0

@JustinValentini它不必杂乱:'$ name =“foobar”; array_map(函数($ obj)use($ name){return $ obj - > {$ name};},$ documents);' – Andrea 2015-01-07 15:47:33

+0

另外,使用'create_function'是一个坏主意。没有人再使用PHP 5.2 - 如果它们是,那是一个严重的安全问题。改为使用闭包。 – Andrea 2015-01-07 15:49:29

1

另一种方法是使用“富” Array对象,像那些在其他语言

发现例如

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(); 
0

一个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}; 
    } 
} 
+0

你不需要在PHP中传递类作为引用,它们是默认的。 – Cobby 2011-12-19 01:19:19

0

感谢您的投入。我想我只是用我同事的解决方案:

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

加载Magento的收集,而且比该集合中再次循环,所以你可以添加你需要的值数组是无效的。适当的方法是使用getColumnValues()方法。此方法将通过指定列名称为您提供一组值。

这是做这件事的适当方法。

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

$yourArray = $collection->getColumnValues('customer_id'); 

这将为您提供一个数组,其中包含您选择的所有customer_id值。

3

您可以ouzo 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/en/latest/utils/functions.html#extract

另请参见函数编程与ouzo(我不能发布链接)。