Sortowanie tablicy według kluczy na podstawie innej tablicy?

Czy w PHP można zrobić coś takiego? Jak napisałbyś jakąś funkcję? Oto przykład. Kolejność jest najważniejsza.

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

I chciałbym zrobić coś takiego

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

Ponieważ na końcu używam foreach () i nie są one w odpowiedniej kolejności(ponieważ dołączam wartości do łańcucha znaków, który musi być w odpowiedniej kolejności i nie wiem z góry wszystkich kluczy/wartości tablicy).

Przejrzałem wewnętrzną tablicę PHP funkcje, ale wydaje się, że można sortować tylko alfabetycznie lub numerycznie.

Author: JasonMArcher, 2008-12-08

15 answers

Wystarczy użyć array_merge lub array_replace. Array_merge działa zaczynając od podanej tablicy (w odpowiedniej kolejności) i nadpisując / dodając klucze z danymi z rzeczywistej tablicy:

$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-odpowiadam na to "nieświeże" pytanie, ponieważ myślę, że wszystkie pętle podane jako poprzednie odpowiedzi są przesadne.

 285
Author: Darkwaltz4,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-23 18:01:43

Proszę bardzo:

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;
}
 94
Author: Eran Galperin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-30 00:48:49

Inny sposób dla 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);

Wynik:

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

Działa dobrze z klawiszami łańcuchowymi i numerycznymi.

 33
Author: ekbUser,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-31 13:48:24

Co powiesz na to rozwiązanie

$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));
});
 27
Author: Peter de Groot,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-25 13:59:12
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;
}
 21
Author: OIS,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-12-08 05:27:22

Weź jedną tablicę jako zamówienie:

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

Można sortować inną tablicę na podstawie wartości za pomocą array_intersectDocs:

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

Lub w Twoim przypadku, aby sortować według kluczy, użyj array_intersect_keyDocs:

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

Obie funkcje zachowają kolejność pierwszego parametru i zwrócą tylko wartości (lub klucze) z drugiej tablicy.

Więc dla tych dwóch standardowych przypadków nie trzeba pisać funkcji na własną rękę, aby wykonać sortowanie/przestawianie.

 14
Author: hakre,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-12-28 18:20:52

Użyłem rozwiązania Darkwaltz4, ale użyłem array_fill_keys zamiast array_flip, aby wypełnić NULL, Jeśli klucz nie jest ustawiony w $array.

$properOrderedArray = array_replace(array_fill_keys($keys, null), $array);
 3
Author: Baptiste Bernard,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-27 08:07:00

Jeśli masz tablicę w tablicy, będziesz musiał dostosować funkcję przez Eran trochę...

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;
}
 2
Author: Boombastic,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-10-29 21:22:48

Bez magii...

$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
Author: Jenovai Matyas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-06 09:48:37

Ta funkcja zwraca tablicę pod i posortowaną w drugim parametrze $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));
}

Przykład:

$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];
 1
Author: Doglas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-31 12:31:34

PHP ma funkcje, które Ci w tym pomogą:

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

// sort array
usort($arrayToBeSorted, function($a, $b) use ($order){
    // sort using the numeric index of the second array
    $valA = array_search($a, $order);
    $valB = array_search($b, $order);

    // move items that don't match to end
    if ($valA === false)
        return -1;
    if ($valB === false)
        return 0;

    if ($valA > $valB)
        return 1;
    if ($valA < $valB)
        return -1;
    return 0;
});

Usort wykonuje całą pracę za Ciebie, a array_search dostarcza klucze. array_search () zwraca false, gdy nie może znaleźć dopasowania, więc elementy, które nie znajdują się w tablicy sortowania, w naturalny sposób przenoszą się na dół tablicy.

Notatka: uasort() uporządkuje tablicę bez wpływu na relacje key => value.

 0
Author: danielcraigie,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-25 15:12:21
  • Sortuj zgodnie z żądaniem
  • Zapisz dla int-keys (z powodu array_replace)
  • nie zwracaj kluczy nie istnieją w inputArray
  • (opcjonalnie) klucze filtrujące nieistniejące w podanej liście kluczy

Kod:

 /**
 * sort keys like in key list
 * filter: remove keys are not listed in keyList
 * ['c'=>'red', 'd'=>'2016-12-29'] = sortAndFilterKeys(['d'=>'2016-12-29', 'c'=>'red', 'a'=>3 ]], ['c', 'd', 'z']){
 *
 * @param array $inputArray
 * @param string[]|int[] $keyList
 * @param bool $removeUnknownKeys
 * @return array
 */
static public function sortAndFilterKeys($inputArray, $keyList, $removeUnknownKeys=true){
    $keysAsKeys = array_flip($keyList);
    $result = array_replace($keysAsKeys, $inputArray); // result = sorted keys + values from input + 
    $result = array_intersect_key($result, $inputArray); // remove keys are not existing in inputArray 
    if( $removeUnknownKeys ){
        $result = array_intersect_key($result, $keysAsKeys); // remove keys are not existing in keyList 
    }
    return $result;
}
 0
Author: Grain,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-29 10:21:57

Pierwsza Sugestia

function sortArrayByArray($array,$orderArray) {
    $ordered = array();
    foreach($orderArray as $key) {
        if(array_key_exists($key,$array)) {
            $ordered[$key] = $array[$key];
            unset($array[$key]);
        }
    }
    return $ordered + $array;
}

Druga Sugestia

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

Chciałem podkreślić, że obie te sugestie są niesamowite. Są to jednak jabłka i pomarańcze. Różnica? Jeden jest przyjazny asocjacyjnie, a drugi jest przyjazny asocjacyjnie. Jeśli używasz 2 tablic w pełni asocjacyjnych, tablica merge / flip faktycznie Scali i nadpisze drugą tablicę asocjacyjną. W moim przypadku to nie są wyniki, których szukałem. Użyłem ustawienia.INI file to create my tablica kolejności sortowania. Tablica danych, którą sortowałem, nie musiała być zapisywana przez mój odpowiednik sortowania asocjacyjnego. Tak więc scalanie tablicy zniszczyłoby moją tablicę danych. Obie są świetnymi metodami, obie muszą być zarchiwizowane w dowolnym zestawie narzędzi programistycznych. W zależności od twoich potrzeb możesz znaleźć obie koncepcje w swoich archiwach.

 0
Author: user1653711,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-10 08:29:40

Przyjąłem odpowiedź od @ Darkwaltz4 ze względu na jej zwięzłość i chciałbym podzielić się tym, jak zaadaptowałem rozwiązanie do sytuacji, w których tablica może zawierać różne klucze dla każdej iteracji w ten sposób:

Array[0] ...
['dob'] = '12/08/1986';
['some_key'] = 'some value';

Array[1] ...
['dob'] = '12/08/1986';

Array[2] ...
['dob'] = '12/08/1986';
['some_key'] = 'some other value';

I utrzymał "klucz główny" w ten sposób:

$master_key = array( 'dob' => ' ' ,  'some_key' => ' ' );

Array_merge wykonałoby scalenie w iteracji tablicy [1] na podstawie $master_key i wytworzyło ['some_key']=", pustą wartość dla tej iteracji. Dlatego array_intersect_key został użyty do modyfikacji $master_key w każdym iterations like so:

foreach ($customer as $customer) {
  $modified_key = array_intersect_key($master_key, $unordered_array);
  $properOrderedArray = array_merge($modified_key, $customer);
}
 0
Author: Pageii Studio,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-26 08:50:51

Trochę za późno, ale nie mogłem znaleźć sposobu, w jaki go zaimplementowałem, ta wersja wymaga zamknięcia, php > =5.3, ale może być zmieniona nie na:

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

$order = array('name', 'dob', 'address');

$keys= array_flip($order);
uksort($customer, function($a, $b)use($keys){
    return $keys[$a] - $keys[$b];
});
print_r($customer);

Oczywiście 'dontSortMe' musi być uporządkowane i może pojawić się najpierw w przykładzie

 -1
Author: DJules,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-29 13:13:06