Сортировка массива по ключам на основе другого массива?

Возможно ли в 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, но, похоже, вы можете сортировать только по алфавиту или численно.

Solutions Collecting From Web of "Сортировка массива по ключам на основе другого массива?"

Просто используйте 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 – Я отвечаю на этот «устаревший» вопрос, потому что я думаю, что все циклы, представленные в качестве предыдущих ответов, являются излишними.

Там вы идете:

 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; } с 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; } 

Другой способ для 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 ) 

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

 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; } 

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

 $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)); }); 

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

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

Вы можете отсортировать другой массив на основе значений с помощью array_intersect Docs :

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

Или в вашем случае, чтобы сортировать по ключам, используйте array_intersect_key Docs :

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

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

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

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

 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; } с 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; } 

Эта функция возвращает вспомогательный и отсортированный массив, основанный на втором параметре $ 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]; 

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

 $properOrderedArray = array_replace(array_fill_keys($keys, null), $array); 

У PHP есть функции, которые помогут вам в этом:

 $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 выполняет всю работу для вас, а array_search предоставляет ключи. array_search () возвращает false, когда не может найти совпадение, поэтому элементы, которые не находятся в массиве сортировки, естественно перемещаются в нижнюю часть массива.

Примечание: uasort () будет заказывать массив без влияния на отношения key => value.

  • сортировать по запросу
  • сохранить для int-keys (из-за array_replace)
  • не возвращать ключи не существуют в inputArray
  • (необязательно) ключей фильтра, отсутствующих в данном ключевом списке

Код:

  /** * 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; } 

Первое предложение

 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; } с 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; } 

Второе предложение

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

Я хотел бы отметить, что оба эти предложения являются удивительными. Тем не менее, это яблоки и апельсины. Разница? Один из них не является ассоциативным, а другой – ассоциативным. Если вы используете 2 полностью ассоциативных массива, то массив merge / flip фактически объединит и перезапишет другой ассоциативный массив. В моем случае это не те результаты, которые я искал. Я использовал файл settings.ini для создания массива порядка сортировки. Массив данных, который я сортировал, не нуждался в написании моей ассоциативной сортировки. Таким образом, слияние массива приведет к уничтожению массива данных. Оба являются отличными методами, и они должны быть заархивированы в любом наборе инструментов разработчиков. На основе ваших потребностей вы можете найти, что вам действительно нужны обе концепции в ваших архивах.

Я принял ответ от @ Darkwaltz4 за его краткость и хотел бы поделиться тем, как я адаптировал решение к ситуациям, где массив может содержать разные ключи для каждой итерации:

 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'; 

и поддерживал «главный ключ» следующим образом:

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

array_merge выполнил бы слияние в Array [1] итерации на основе $ master_key и произвел ['some_key'] = '', пустое значение для этой итерации. Следовательно, array_intersect_key использовался для изменения $ master_key в каждой итерации следующим образом:

 foreach ($customer as $customer) { $modified_key = array_intersect_key($master_key, $unordered_array); $properOrderedArray = array_merge($modified_key, $customer); } 

Немного поздно, но я не мог найти способ, которым я его реализовал, эта версия требует закрытия, php> = 5.3, но может быть изменена не для:

 $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); 

Конечно, «dontSortMe» нужно сортировать и может показаться первым в примере