Сортировать массив по ключам на основе другого массива? - PullRequest
126 голосов
/ 08 декабря 2008

Возможно ли в PHP сделать что-то подобное? Как бы вы пошли о написании функции? Вот пример. Порядок - самая важная вещь.

$customer['address'] = '123 fake st';
$customer['name'] = 'Tim';
$customer['dob'] = '12/08/1986';
$customer['dontSortMe'] = 'this value doesnt need to be sorted';

И я бы хотел сделать что-то вроде

$properOrderedArray = sortArrayByArray($customer, array('name', 'dob', 'address'));

Потому что в конце я использую foreach (), а они не в правильном порядке (потому что я добавляю значения в строку, которая должна быть в правильном порядке, и я не знаю заранее все ключи / значения массива).

Я просмотрел функции внутреннего массива PHP, но кажется, что вы можете сортировать только по алфавиту или по цифрам.

Ответы [ 15 ]

309 голосов
/ 01 февраля 2012

Просто используйте array_merge или array_replace. Array_merge работает, начиная с заданного вами массива (в правильном порядке) и переписывая / добавляя ключи с данными из вашего фактического массива:

$customer['address'] = '123 fake st';
$customer['name'] = 'Tim';
$customer['dob'] = '12/08/1986';
$customer['dontSortMe'] = 'this value doesnt need to be sorted';

$properOrderedArray = array_merge(array_flip(array('name', 'dob', 'address')), $customer);
//Or:
$properOrderedArray = array_replace(array_flip(array('name', 'dob', 'address')), $customer);

//$properOrderedArray -> array('name' => 'Tim', 'address' => '123 fake st', 'dob' => '12/08/1986', 'dontSortMe' => 'this value doesnt need to be sorted')

ps - я отвечаю на этот «устаревший» вопрос, потому что я думаю, что все циклы, указанные в предыдущих ответах, излишни.

96 голосов
/ 08 декабря 2008

Вот, пожалуйста:

function sortArrayByArray(array $array, array $orderArray) {
    $ordered = array();
    foreach ($orderArray as $key) {
        if (array_key_exists($key, $array)) {
            $ordered[$key] = $array[$key];
            unset($array[$key]);
        }
    }
    return $ordered + $array;
}
34 голосов
/ 31 марта 2013

Другой способ для PHP> = 5.3.0:

$customer['address'] = '123 fake st';
$customer['name'] = 'Tim';
$customer['dob'] = '12/08/1986';
$customer['dontSortMe'] = 'this value doesnt need to be sorted';

$customerSorted = array_replace(array_flip(array('name', 'dob', 'address')), $customer);

Результат:

Array (
  [name] => Tim
  [dob] => 12/08/1986
  [address] => 123 fake st
  [dontSortMe] => this value doesnt need to be sorted
)

Прекрасно работает со строковыми и числовыми клавишами.

31 голосов
/ 25 ноября 2014

Как насчет этого решения

$order = array(1,5,2,4,3,6);

$array = array(
    1 => 'one',
    2 => 'two',
    3 => 'three',
    4 => 'four',
    5 => 'five',
    6 => 'six'
);

uksort($array, function($key1, $key2) use ($order) {
    return (array_search($key1, $order) > array_search($key2, $order));
});
22 голосов
/ 08 декабря 2008
function sortArrayByArray(array $toSort, array $sortByValuesAsKeys)
{
    $commonKeysInOrder = array_intersect_key(array_flip($sortByValuesAsKeys), $toSort);
    $commonKeysWithValue = array_intersect_key($toSort, $commonKeysInOrder);
    $sorted = array_merge($commonKeysInOrder, $commonKeysWithValue);
    return $sorted;
}
13 голосов
/ 28 декабря 2011

Возьмите один массив в качестве вашего заказа:

$order = array('north', 'east', 'south', 'west');

Вы можете отсортировать другой массив на основе значений, используя array_intersect & shy; Документы :

/* sort by value: */
$array = array('south', 'west', 'north');
$sorted = array_intersect($order, $array);
print_r($sorted);

Или в вашем случае для сортировки по ключам используйте array_intersect_key & shy; Документы :

/* sort by key: */
$array = array_flip($array);
$sorted = array_intersect_key(array_flip($order), $array);
print_r($sorted);

Обе функции сохранят порядок первого параметра и будут возвращать только значения (или ключи) из второго массива.

Таким образом, для этих двух стандартных случаев вам не нужно самостоятельно писать функцию для выполнения сортировки / реорганизации.

5 голосов
/ 27 июня 2017

Я использовал решение Darkwaltz4, но использовал array_fill_keys вместо array_flip, чтобы заполнить NULL, если ключ не установлен в $array.

$properOrderedArray = array_replace(array_fill_keys($keys, null), $array);
3 голосов
/ 06 апреля 2018

Без магии ...

$array=array(28=>c,4=>b,5=>a);
$seq=array(5,4,28);    
SortByKeyList($array,$seq) result: array(5=>a,4=>b,28=>c);

function sortByKeyList($array,$seq){
    $ret=array();
    if(empty($array) || empty($seq)) return false;
    foreach($seq as $key){$ret[$key]=$dataset[$key];}
    return $ret;
}
2 голосов
/ 30 октября 2009

Если у вас есть массив в вашем массиве, вам придется немного адаптировать функцию Эрана ...

function sortArrayByArray($array,$orderArray) {
    $ordered = array();
    foreach($orderArray as $key => $value) {
        if(array_key_exists($key,$array)) {
                $ordered[$key] = $array[$key];
                unset($array[$key]);
        }
    }
    return $ordered + $array;
}
1 голос
/ 20 января 2017

Эта функция возвращает подчиненный и отсортированный массив на основе второго параметра $ keys

function array_sub_sort(array $values, array $keys){
    $keys = array_flip($keys);
    return array_merge(array_intersect_key($keys, $values), array_intersect_key($values, $keys));
}

Пример:

$array_complete = [
    'a' => 1,
    'c' => 3,
    'd' => 4,
    'e' => 5,
    'b' => 2
];

$array_sub_sorted = array_sub_sort($array_complete, ['a', 'b', 'c']);//return ['a' => 1, 'b' => 2, 'c' => 3];
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...