Est-il possible dans PHP de faire quelque chose comme ça? Comment feriez-vous pour écrire une fonction? Voici un exemple. L'ordre est la chose la plus importante.
$customer['address'] = '123 fake st';
$customer['name'] = 'Tim';
$customer['dob'] = '12/08/1986';
$customer['dontSortMe'] = 'this value doesnt need to be sorted';
Et j'aimerais faire quelque chose comme
$properOrderedArray = sortArrayByArray($customer, array('name', 'dob', 'address'));
Parce que finalement, j'utilise un foreach () et ils ne sont pas dans le bon ordre (parce que j'ajoute les valeurs à une chaîne qui doit être dans le bon ordre et que je ne connais pas à l'avance toutes les clés valeurs).
J'ai parcouru les fonctions de tableau internes de PHP, mais il semble que vous ne pouvez trier que par ordre alphabétique ou numérique.
Utilisez simplement array_merge
ou array_replace
. Array_merge
fonctionne en commençant par le tableau que vous donnez (dans le bon ordre) et en écrasant/ajoutant les clés avec les données de votre tableau actuel:
$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 - Je réponds à cette question obsolète, car je pense que toutes les boucles données dans les réponses précédentes sont excessives.
Voilà:
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;
}
Une autre façon pour 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);
Résultat:
Array (
[name] => Tim
[dob] => 12/08/1986
[address] => 123 fake st
[dontSortMe] => this value doesnt need to be sorted
)
Fonctionne bien avec une chaîne et des touches numériques.
Que diriez-vous de cette solution
$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));
});
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;
}
Prenez un tableau comme commande:
$order = array('north', 'east', 'south', 'west');
Vous pouvez trier un autre tableau en fonction de valeurs à l’aide de array_intersect
Docs :
/* sort by value: */
$array = array('south', 'west', 'north');
$sorted = array_intersect($order, $array);
print_r($sorted);
Ou dans votre cas, pour trier les clés, utilisez array_intersect_key
Docs :
/* sort by key: */
$array = array_flip($array);
$sorted = array_intersect_key(array_flip($order), $array);
print_r($sorted);
Les deux fonctions conserveront l'ordre du premier paramètre et renverront uniquement les valeurs (ou clés) du second tableau.
Ainsi, pour ces deux cas standard, vous n'avez pas besoin d'écrire une fonction pour effectuer le tri/la réorganisation.
J'ai utilisé la solution de Darkwaltz4, mais j'ai utilisé array_fill_keys
au lieu de array_flip
, pour remplir avec NULL
si une clé n'est pas définie dans $array
.
$properOrderedArray = array_replace(array_fill_keys($keys, null), $array);
SI vous avez un tableau dans votre tableau, vous devrez adapter un peu la fonction de Eran ...
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;
}
Sans magie ...
$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;
}
Cette fonction retourne un tableau sous et trié basé sur le second paramètre $ 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));
}
Exemple:
$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];
PHP a des fonctions pour vous aider avec ceci:
$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 fait tout le travail pour vous et array_search fournit les clés. array_search () renvoie false lorsqu'il ne trouve pas de correspondance. Les éléments qui ne figurent pas dans le tableau de tri se déplacent naturellement vers le bas.
Remarque: uasort () ordonnera le tableau sans affecter les relations clé => valeur.
Code:
/**
* 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;
}
Première suggestion
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;
}
Deuxième suggestion
$properOrderedArray = array_merge(array_flip(array('name', 'dob', 'address')), $customer);
Je voulais souligner que ces deux suggestions sont géniales. Cependant, ce sont des pommes et des oranges. La différence? L'un est convivial non-associatif et l'autre est convivial. Si vous utilisez 2 tableaux totalement associatifs, la fusion/retournement de tableau fusionnera et remplacera l'autre tableau associatif. Dans mon cas, ce ne sont pas les résultats que je cherchais. J'ai utilisé un fichier settings.ini pour créer mon tableau d'ordre de tri. Le tableau de données que je triais n'a pas besoin d'être remplacé par mon homologue de tri associatif. Ainsi, la fusion de tableaux détruirait mon tableau de données. Les deux méthodes sont excellentes et doivent être archivées dans une boîte à outils de développement. En fonction de vos besoins, vous constaterez peut-être que vous avez réellement besoin des deux concepts dans vos archives.
J'ai adopté la réponse de @ Darkwaltz4 pour sa brièveté et je voudrais partager comment j'ai adapté la solution aux situations où le tableau peut contenir différentes clés pour chaque itération, comme ceci:
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';
et maintenu une "clé principale" comme ceci:
$master_key = array( 'dob' => ' ' , 'some_key' => ' ' );
array_merge aurait exécuté la fusion dans l'itération Array [1] en fonction de $ master_key et aurait produit ['some_key'] = '', une valeur vide pour cette itération. Ainsi, array_intersect_key a été utilisé pour modifier $ master_key dans chaque itération de la manière suivante:
foreach ($customer as $customer) {
$modified_key = array_intersect_key($master_key, $unordered_array);
$properOrderedArray = array_merge($modified_key, $customer);
}