如果存在相同的数字数组键,则添加一个增量

时间:2016-03-14 07:38:12

标签: php arrays on-duplicate-key array-key array-key-exists

我有一个以下数组,我需要根据键值对此数组进行排序。如果所有数字键都不同,我写了一个代码并得到了完美的结果。

$myarray_need_to_sort =Array
(
    [13] => 214
    [14] => 215
    [15] => 216
    [21] => 223
)

这是我的代码

$order = array();
foreach ($myarray_need_to_sort as $value){
    $cat = Mage::getModel('catalog/category')->load($value);
    $order[$cat->getTabOrder()] = $value;
}   
ksort($order);
$sorted_order = array();
foreach ($order as $key=>$value)
{
    $sorted_order[$key] = $value;
}

print_r($sorted_order);

$ cat-> getTabOrder()是我从后端获得的排序顺序,结果是完美的

Array
(
    [1] => 216
    [2] => 223
    [3] => 215
    [4] => 214
)

代码正在完美地排序数组,但问题是如果存在相同的密钥,即有人添加了$ cat-> getTabOrder(),对于两个值,同样说2和2,那么它将删除一个密钥。我需要为此添加一个增量,如

Array
(
    [1] => 216
    [2] => 223
    [2] => 215 -- it should be 3 and 4 should be 5 but it is removing 2 from here
    [4] => 214 -- should be 5
)

1 个答案:

答案 0 :(得分:0)

正如我在评论中所说,这看起来像XY problem。您实际上并不需要递增密钥,您需要保留所有值(包括密钥重复时)并按密钥对它们进行排序。

我假设当两个或多个项目具有相同的密钥时,它们来自数据库的顺序必须保存在最终列表中。

目标是:

  • 保留所有值;
  • 按键排序;
  • 当两个或多个项目具有相同的密钥时,请保留它们到达的顺序。

考虑到这一点,一个可能的解决方案是在$order中为每个密钥保留具有该密钥的项目列表。按键对列表进行排序,然后使用两个嵌套的foreach循环遍历数组,或者在使用之前将其展平。

代码:

// $order[$key] is the list of $cat items having $cat->getTabOrder() == $key
$order = array();
foreach ($myarray_need_to_sort as $value){
    $cat = Mage::getModel('catalog/category')->load($value);
    $key = $cat->getTabOrder();
    if (! array_key_exists($key, $order)) {
        // This is the first $cat having $key as tab order
        // Create a new list of $key
        $order[$key] = array();
    }
    // Add $value to the list of is $key (tab order)
    $order[$key][] = $value;
}
// Sort the outer array by keys
ksort($order);

print_r($order)应显示如下内容:

Array
(
    [1] => Array
        (
            [0] => 216
        )
    [2] => Array
        (
            [0] => 223
            [1] => 215
        )
    [4] => Array
        (
            [0] => 214
        )
)

现在,您可以通过遍历每个子数组来检索数组中的值:

foreach ($order as $key => $list) {
    foreach ($list as $value) {
        echo('$key='.$key.': $value='.$value."\n");
    }
}

显示:

$key=1: $value=216
$key=2: $value=223
$key=2: $value=215
$key=4: $value=214

如果您不再关心密钥,您需要的是排序后的$value列表,那么您可以将值放入上面双foreach的新列表中(而不是显示它们。)

或者您可以使用array_reduce()array_merge()以更紧凑的方式撰写:

$new = array_reduce($order, 'array_merge', array());
print_r($new);

输出结果为:

Array
(
    [0] => 216
    [1] => 223
    [2] => 215
    [3] => 214
)

请注意原始密钥丢失,新列表按顺序编制索引。