2016-04-30 11 views
2

TL:DR:DoctrineのArrayCollectionでキーを設定せずに配列のマッピングしかサポートしていないのはなぜですか?ArrayCollection :: mapを使って連想配列を作成する

は、私は私のDoctrineのエンティティからの連想配列(キー - >値)を作成したい:つまりcustomerId => CustomerNameuserId => userNameなど連想配列を作成することはロケット科学ではありませんので、これを達成するために、他の多くの方法があります。

しかし、私はまだArrayCollection:map(または同様の方法)にこれを行うオプションがないのかと疑問に思っています。キーを持つ配列を作成するには、そのコンストラクタメソッドとArrayCollection::set()がサポートされています。

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

しかし、あなたは ArrayCollection::map()でキーを設定することはできません。あなたもこのような配列を作成することができます。どうして?このような機能を探している最初の開発者ですか(それほど可能性は低いですか)、または、不要、不可能、望ましくない、または悪い習慣になる重要な原則が不足していますか?

答えて

1

私はアダムWathanのブログCustomizing Keys When Mapping Collectionsこの答えを見つけました:

マップ操作中にキーをカスタマイズしたいのこの問題は、私はかなり定期的におよそ聞か ものです。

私は、PHPでは のlistdictionaryの両方を表す同じデータ型を使用しているため、難しい問題と思われる理由が考えられます。

彼はLaravelのコレクションライブラリを使用しています。

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

まさに私が使用したいソリューションですが、それは教義の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); 
    } 
} 
0

しかし、ArrayCollection :: map()でキーを設定することはできません。

マップは、コレクションからマップに変換する機能ではありません。

一般にmap関数はリストからの値に作用し、データ構造から独立しているため、ArrayCollection:mapの動作は非常に自然です。

1

これはArrayCollectionクラスはsource codeに記載される方法である。

ArrayCollectionは、通常のPHP配列をラップCollection実装です。

そのmap()方法はarray_map()によって返されたPHPの配列をラップし、新しいArrayCollectionオブジェクトを返しますarray_map()の単なるラッパーです。

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() 1つ以上のアレイを使用して起動することができる(2番目の引数で始まります)。 ArrayCollection::map()は、1つの配列(ラップする配列)だけを使用して呼び出します。単一の配列で呼び出された場合、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クラスはArrayAccessインタフェースを拡張Collectionインターフェイスを実装するために角括弧を使用してアクセスが働きます。

関連する問題