2013-07-03 2 views
7

У меня есть метод в классе, который выглядит следующим образом:PHP sorting 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)); 
    } 

Но это не полезно, так как абонент метода не знает порядок пар ключ/элементов в ассоциативный массив в переменной экземпляра $ скрытом. В идеале возвращаемый массив будет в том же порядке, что и ключи, указанные в списке $. Например:

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

я могу легко написать некоторые явные, многословный PHP код в цикле, чтобы сделать это, но есть какой-то хитрый способ использовать различные функции массива, например, array_multisort(), чтобы выплюнуть это в минимальных строках кода (и, надеюсь, при скомпилированной скорости кода - я проверю его, если это имеет значение).

В некотором смысле, это мозговой тизер, которому я еще не знаю ответа. Это не критично, я делаю это без явного цикла, но мне любопытно, можно ли это сделать. Я потратил около 30 минут на это и еще не нашел решение.

+0

+1 причина мне нравится этот вопрос, но я также хочу, чтобы убедиться, что вы известно о 'extract()'. – goat

+0

Я знаю об экстракт(). Я пытаюсь явно избегать этого в моем классе, который имеет этот метод, так как легко вызвать проблемы с безопасностью, если 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 
) 
*/ 
Смежные вопросы