2013-07-03 10 views
7

私はこのようなクラスのメソッドを持っています。メソッドの呼び出し元は、隠されたインスタンス変数$で連想配列のキー/要素のペアの順序を知らないので、PHPは2番目の配列でarray_intersect_key()の結果をソートします

class SomeClass { 
    private $hidden = array(....); 

    /** 
    * @return array - numeric indexed array in order of $this->hidden. 
    * Suitable for use by list(var1, var2, ...) 
    */ 
    public function getAsList($list = array()) 
    { 
     return array_values(array_intersect_key($this->hidden, array_flip($list)); 
    } 

は、しかし、これは、有用ではありません。理想的には、返される配列は、$ listで指定されたキーと全く同じ順序になります。例えば:

$foo = new SomeClass(); 
list($foo, $bar, $baz) = $foo->getAsList(array('foo', 'bar', 'baz'); 

例えば、私は簡単にこれを行うには、ループ内のいくつかの明示的な、冗長なPHPコードを書くことができるが、種々の配列の機能を使用するためのいくつかの巧妙な方法がありますarray_multisort()を使って最小限のコード行で吐き出すことができます(そしてうまくいけば、コンパイルされたコードの速度でテストします)。

ある意味では、これは私がまだ答えを知らない脳の試練です。私はそれを明示的なループなしに行うことは重要ではありませんが、それができるかどうか不思議です。私は30分くらいそれを使いましたが、解決策はまだ見つかりませんでした。

+0

+1原因'extract()'を認識しています。 – goat

+0

私はextract()について知っています。私は明示的にこのメソッドを持つ私のクラスで回避しようとしています。なぜなら、extract()が間違って使われるとセキュリティ上の問題を起こしやすいからです。また、名前付き変数を明示的に作成することは、少なくとも私の小さなベンチマークでは何らかの理由で、実際にはextract()より高速であることが分かりました。 – CXJ

答えて

7

おそらくarray_replaceはあなたのパズルに欠けている:

public function getAsList($list = array()) 
{ 
    $klist = array_flip($list); 
    return array_values(array_intersect_key(array_replace($klist, $this->hidden), $klist)); 
} 

例(Demo):私は質問を好きですが、私はまた、あなたがしているようにしたい

$hidden = [ 
    'apples' => 19, 
    'eggs' => 7, 
    'grapes' => 144, 
    'mushrooms' => 3, 
    'oranges' => 16 
]; 

$list = ['grapes', 'apples', 'eggs', 'oranges']; 

$klist = array_flip($list); 
print_r(array_values(array_intersect_key(array_replace($klist, $hidden), $klist))); 

/* 
Array 
(
    [0] => 144 
    [1] => 19 
    [2] => 7 
    [3] => 16 
) 
*/ 
関連する問題