通过基于另一个数组的键sorting数组?

是否有可能在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(),而且它们的顺序并不正确(因为我将这些值附加到了一个string,这个string需要按照正确的顺序排列,而且我不知道所有的数组键/值)。

我已经看过PHP的内部数组函数,但它似乎只能按字母或数字sorting。

只要使用array_mergearray_replaceArray_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; } 

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 ) 

可以正常使用string和数字键。

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

这个解决scheme如何?

 $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根据值对另一个数组进行sorting:

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

或者你的情况,按键sorting,使用array_intersect_key 文档

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

这两个函数将保持第一个参数的顺序,并只会返回第二个数组的值(或键)。

所以对于这两种标准的情况,你不需要自己写一个函数来执行sorting/重新排列。

如果你的数组中有数组,你将不得不通过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; } 

该函数返回一个基于第二个参数$ keys的子数组和sorting数组

 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的解决scheme,但是使用array_fill_keys而不是array_flip来填充NULL如果在$array没有设置键。

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

PHP的function可以帮助你:

 $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,所以不在sort数组中的项自然移动到数组的底部。

注意:uasort()将在不影响key =>值关系的情况下对数组进行sorting。

  • 按要求sorting
  • 保存为int键(因为array_replace)
  • inputArray中不存在返回键
  • (可选)筛选键在给定keyList中不存在

码:

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

第一个build议

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

第二个build议

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

我想指出这两个build议都很棒。 但是,他们是苹果和橘子。 区别? 一个是非联想友好的,另一个是联想友好的。 如果你正在使用2个完全关联的数组,那么数组合并/翻转将实际上合并并覆盖另一个关联数组。 在我的情况下,这不是我正在寻找的结果。 我用settings.ini文件来创build我的sorting顺序数组。 我正在sorting的数据数组不需要由我的联合sorting对象来完成。 因此arrays合并会破坏我的数据数组。 两者都是很好的方法,都需要在任何开发人员工具箱中归档。 根据您的需求,您可能会发现您实际上在档案中需要这两个概念。

为了简洁起见,我采用了@ Darkwaltz4的答案,并希望分享我如何将解决scheme适用于数组可能包含不同密钥的情况,如下所示:

 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会根据$ master_key在Array [1]迭代中执行合并,并为该迭代生成['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); } 

有点迟了,但是我找不到实现它的方式,这个版本需要closures,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'需要被整理出来,并且可能会在示例中首先出现