2009-11-03 54 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(我不能發佈鏈接)。