基于另一个数组按键对数组进行排序?

时间:2008-12-08 00:24:16

标签: php arrays 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()并且它们的顺序不正确(因为我将值附加到需要按正确顺序排列的字符串中,并且我事先并不知道所有的数组键/值)。

我查看了PHP的内部数组函数,但似乎只能按字母顺序或数字顺序排序。

16 个答案:

答案 0 :(得分:309)

只需使用array_mergearray_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 - 我正在回答这个“陈旧”的问题,因为我认为以前的答案给出的所有循环都是过度的。

答案 1 :(得分:96)

你去了:

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

答案 2 :(得分:34)

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
)

使用字符串和数字键可以正常工作。

答案 3 :(得分:31)

这个解决方案怎么样

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

答案 4 :(得分:22)

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

答案 5 :(得分:14)

将一个数组作为您的订单:

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

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

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

答案 6 :(得分:5)

我使用了Darkwaltz4的解决方案,但使用array_fill_keys代替array_flip,如果NULL中没有设置密钥,则填充$array

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

答案 7 :(得分:3)

没有魔法......

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

答案 8 :(得分:2)

如果您的数组中有数组,则必须稍微调整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;
}

答案 9 :(得分:1)

此函数返回基于第二个参数$ 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];

答案 10 :(得分:0)

第一个建议

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文件来创建排序顺序数组。我正在排序的数据数组不需要由我的关联排序对应物写入。因此,数组合并会破坏我的数据数组。两者都是很好的方法,都需要在任何开发人员工具箱中存档。根据您的需求,您可能会发现在档案中确实需要这两个概念。

答案 11 :(得分:0)

我采用@ 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将基于$ 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);
}

答案 12 :(得分:0)

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 =&gt;价值关系。

答案 13 :(得分:0)

  • 按要求排序
  • 保存为int-keys(因为array_replace)
  • 不在inputArray中存在返回键
  • (可选)过滤键在给定的keyList中不存在

代码:

public static void main(String[] args) {
 String dateStr = "29/12/2016";
 SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
 try {
  Date date = sdf.parse(dateStr);
  sdf = new SimpleDateFormat("dd-MM-yyyy");
  System.out.println(sdf.format(date));
 } catch (ParseException e) {
  e.printStackTrace();
 }
}

答案 14 :(得分:0)

如果您有这样的数组,并且需要根据顺序对数组进行排序,则可以轻松使用以下代码:

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

答案 15 :(得分:-1)

有点晚了,但是我无法找到实现它的方式,这个版本需要关闭,php&gt; = 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);

当然&#39; dontSortMe&#39;需要整理出来,并且可能首先出现在示例中