我在开发过程中经常遇到的一种模式是尝试从一组对象中收集一个列/属性值到一个数组中。例如:
$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应该在很久以前解决的问题?
答案 0 :(得分:10)
您可以使用array_map()功能来实现此目的:
function getName($obj) {
return $obj->name;
}
$documentsName = array_map("getName", $documents);
如果您不想在全局命名空间中创建 getName()函数,也可以考虑lambda函数的create_function()函数。
在 PHP 5.3 中,你甚至可以这样做:
$documentsName = array_map(function ($obj) { return $obj->name; }, $documents);
答案 1 :(得分:3)
您可以使用ouzo goodies
轻松完成$names = array_map(Functions::extract()->name, $documents);
或与阵列(来自ouzo goodies)
$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进行函数式编程(我无法发布链接)。
答案 2 :(得分:1)
另一种方法是使用“富”数组对象,就像在其他语言中找到的那样
例如
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();
答案 3 :(得分: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};
}
}
答案 4 :(得分:0)
感谢投票人员。我想我只是想使用我的同事的解决方案:
class BaseUtil
{
public static function collect($collection, $property) {
$values = array();
foreach ($collection as $item) {
$values[] = $item->{$property};
}
return $values;
}
}
答案 5 :(得分:0)
加载Magento集合,然后再在该集合中循环,以便将所需的值添加到数组中,这是无效的。执行此操作的适当方法是使用getColumnValues()方法。此方法将通过指定列名称为您提供一组值。
这是执行此操作的适当方法。
$collection =Mage::getModel('your/object')->getCollection()
->addFieldToSelect('customer_id');
$yourArray = $collection->getColumnValues('customer_id');
这将为您提供一个包含您选择的所有customer_id值的数组。