2013-07-03 24 views
7

我有一个类中的方法看起来像这样;PHP排序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 
) 
*/