基于另一个 Array 按键排序 Array?

有没有可能在 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 的内部数组函数,但似乎只能按字母或数字排序。

177747 次浏览

这就对了:

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 $toSort, array $sortByValuesAsKeys)
{
$commonKeysInOrder = array_intersect_key(array_flip($sortByValuesAsKeys), $toSort);
$commonKeysWithValue = array_intersect_key($toSort, $commonKeysInOrder);
$sorted = array_merge($commonKeysInOrder, $commonKeysWithValue);
return $sorted;
}

如果你的数组中有数组,你需要调整一下 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;
}

选择一个数组作为你的顺序:

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

您可以使用 array_intersect < sup > < em > & shy; Docs 根据值对另一个数组进行排序:

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

或者在您的情况下,按键排序,使用 array_intersect_key < sup > < em > & shy; Docs :

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

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

因此,对于这两种标准情况,您不需要自己编写函数来执行排序/重新排列。

只要使用 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',
//   'dob'        => '12/08/1986',
//   'address'    => '123 fake st',
//   'dontSortMe' => 'this value doesnt need to be sorted')

PS: 我在回答这个“陈旧”的问题,因为我认为以前的答案给出的所有循环都是过分的。

第一个建议

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

我想指出的是,这两个建议都很棒。然而,它们是苹果和橘子。有什么区别吗?一种是非联想友好型,另一种是联想友好型。如果你使用两个完全关联的数组,那么数组合并/翻转实际上会合并并覆盖其他的关联数组。对我来说,这不是我想要的结果。我使用 setings.ini 文件创建排序顺序数组。我正在排序的数据数组不需要我的关联排序对应方重写。因此数组合并会破坏我的数据数组。两者都是很棒的方法,都需要在任何开发人员工具箱中存档。根据您的需要,您可能会发现实际上需要在您的存档中使用这两个概念。

为了简洁起见,我采用了@Dark waltz4的答案,并想分享一下我是如何根据每次迭代中数组可能包含不同键的情况调整解决方案的,比如:

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]迭代中执行 merge,并为该迭代生成[‘ 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.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
)

使用字符串和数字键可以很好地工作。

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 = > 值关系的情况下对数组进行排序。

这个办法怎么样

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

有点晚了,但我找不到实现它的方法,这个版本需要闭包,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”进行排序,它可能会首先出现在示例中

  • 按要求分类
  • 保存为 int-key (因为 array _ place)
  • 不返回键在 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;
}

此函数根据第二个参数 $key 返回子数组和排序数组

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

我使用了黑暗 Waltz4的解决方案,但是使用了 array_fill_keys而不是 array_flip,以便在 $array中没有设置键的情况下填充 NULL

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

没有魔法。

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

如果您有这样的数组,并且需要根据顺序对数组进行排序,那么您可以很容易地使用下面的代码:

$order = ['a', 'b', 'c', 'd', 'e'];
$needToSortArray = ['d', 'c', 'e'];


uksort($needToSortArray, function($key1, $key2) use ($order, $needToSortArray) {
return (array_search($needToSortArray[$key1], $order) > array_search($needToSortArray[$key2], $order));
});