使用ArrayCollection :: map创建关联数组

时间:2016-04-30 14:01:47

标签: php arrays symfony doctrine-orm

TL; DR:为什么Doctrine的ArrayCollection仅支持在不设置密钥的情况下映射数组?

我想从我的Doctrine实体创建一个关联数组(key-> value):ie customerId => CustomerNameuserId => userName等。创建一个关联数组不是火箭科学,所以还有很多其他方法可以实现这一目标。

但是,我仍然想知道为什么ArrayCollection:map(或类似的方法)没有选项来执行此操作。使用键创建数组是由它的构造方法和ArrayCollection::set()支持的。你甚至可以创建一个这样的数组:

$arraycollection = new ArrayCollection();
$arraycollection->add('John Doe');
$arraycollection->set('foo', 'bar');
$arraycollection->set(418, 'teapot');

但您无法使用ArrayCollection::map()设置密钥。为什么?我是第一个寻找这样的功能的开发人员(不太可能),还是我错过了一个重要原则,使其成为不必要的,不可能的,不可取的或不良的做法?

3 个答案:

答案 0 :(得分:2)

我找到了这个答案Adam Wathan的博客 Customizing Keys When Mapping Collections

  

想要在地图操作期间自定义键的问题是   我经常被问到的事情。

     

我认为它看起来像一个棘手问题的原因是因为在PHP中,   我们使用相同的数据类型来表示listdictionary

他使用Laravel的Collection库:

$emailLookup = $employees->reduce(function ($emailLookup, $employee) {
    $emailLookup[$employee['email']] = $employee['name'];
    return $emailLookup;
}, []);

这正是我想要使用的解决方案,但它不在Doctrine的ArrayCollection中。由于向后兼容性,添加reduce()方法的pull request已关闭。

感谢this example,您可以根据Doctrine的ArrayCollection实现自己的类:

use Doctrine\Common\Collections\ArrayCollection;

class ExtendedArrayCollection extends ArrayCollection
{
    /**
     * Reduce the collection into a single value.
     *
     * @param \Closure $func
     * @param null $initialValue
     * @return mixed
     */
    public function reduce(\Closure $func, $initialValue = null)
    {
        return array_reduce($this->toArray(), $func, $initialValue);
    }
}

答案 1 :(得分:1)

这就是source code

ArrayCollection类的描述方式
  

ArrayCollection是一个包含常规PHP数组的Collection实现。

它的map()方法只是array_map()的包装器,它返回一个新的ArrayCollection对象,该对象包装array_map()返回的PHP数组。

为了使一切清楚,array_map()为数组的每个元素调用一个函数(它的第一个参数);函数返回的值存储在结果数组中。

例如:

$input  = [ 'one' => 1, 'two' => 2, 'three' => 3, ];
$output = array_map(function ($x) { return $x * $x; }, $input);
print_r($output);

输出:

Array
(
    [one] => 1
    [two] => 4
    [three] => 9
)
可以使用一个或多个数组(从第二个参数开始)调用

array_map()ArrayCollection::map()仅使用一个数组(它包装的数组)调用它。当使用单个数组调用它时,array_map()会保留其字符串键(但重新编号数字键)。

<强>修订:

ArrayCollection::map()未设置键或值。它将函数应用于存储在集合中的所有值,并返回一个新集合。

如果需要在类型为ArrayCollection的对象中的指定键上放置值,则可以使用常规PHP语法access array elements using square brackets

以下代码与您在问题中发布的代码等效。

$arraycollection = new ArrayCollection();
$arraycollection[] = 'John Doe';
$arraycollection['foo'] = 'bar';
$arraycollection[418] = 'teapot';

使用方括号进行访问是有效的,因为ArrayCollection类实现了扩展Collection接口的ArrayAccess接口。

答案 2 :(得分:0)

  

但您无法使用ArrayCollection :: map()设置密钥。

地图不是将集合转换为地图的功能。

通常,map函数对列表中的值进行操作,并且独立于数据结构,因此ArrayCollection:map的行为非常自然。