【问题标题】:Sort array using array_multisort使用 array_multisort 对数组进行排序
【发布时间】:2012-06-19 20:28:15
【问题描述】:

我有以下数组:

$array = array(
        'note' => array(),
        'year' => array('2011','2010', '2012'),
        'type' => array('conference', 'journal', 'conference'),
    );

我使用以下函数对数组进行排序,使用字段类型和另一个数组:

function array_multisort_by_order(array $array, $by, array $order)
{
    $order = array_flip($order);
    $params[] = $array[$by];
    foreach($params[0] as &$v) $v = $order[$v];
    foreach($array as &$v) $params[] = &$v; unset($v);
    call_user_func_array('array_multisort', $params);
    return $array;
}

当我调用以下函数时,出现以下错误:

$array = array_multisort_by_order($array, 'type', array('conference', 'journal'));

print_r($array['type']);

错误:

Warning: array_multisort(): Array sizes are inconsistent.

我知道数组是不一致的。有没有更好的功能可以使用?

请查看:codepad

期望的输出:

Array
(
[note] => Array
    (
        [0] => 
        [1] => 
        [2] => 
    )

[year] => Array
    (
        [0] => 2011
        [1] => 2012
        [2] => 2010
    )

[type] => Array
    (
        [0] => conference
        [1] => conference
        [2] => journal
    )

)

示例 2:

数组

 $array = array(
        'note' => array([0]=>'test1', [1]=>'test2'),
        'year' => array([0]=>'2011', [2]=>'2012'),
        'type' => array([0]=>'conference',[1]=>'journal', [2]=>'conference'),
    );

期望的结果 2

Array
(
[note] => Array
    (
        [0] => test1
        [1] => 
        [2] => tes2
    )

[year] => Array
    (
        [0] => 2011
        [1] => 2012
        [2] => 
    )

[type] => Array
    (
        [0] => conference
        [1] => conference
        [2] => journal
    )

)

谢谢

【问题讨论】:

  • 嗯,想要的输出会让事情变得更清楚,然后从代码中查询它。你能提供吗?
  • 好的,剩下 1 个问题:子数组是否总是空的或长度一致,或者我们可以期望这里有一个包含 2 个项目的子数组,如果是,我们该如何处理?假设它们仍然与其他子数组中的前 2 项匹配?
  • @Wrikken:可以在这里找到一个工作示例:codepad.org/mjSBYEyi。不幸的是,子数组总是不一致的。我将提供另一个例子。添加了另一个示例
  • 好的,所以数字键很重要,明白了。
  • 将输入数组填充到一致的长度后,请参阅此页面:stackoverflow.com/q/2474722/2943403

标签: php arrays multidimensional-array


【解决方案1】:

好的,所以,首先想到的解决方案之一是添加空值以使它们保持一致:

function array_multisort_by_order(array $array, $by, array $order)
{
     $max = max(array_map('count',$array));
    //or, alternatively, depending on input (if there are no 'complete' subarrays):
    //$max = max(array_map(function($arr){return max(array_keys($arr));},$array))+1;

    //ADDITION: negative numeric keys:
    $min = min(array_map(function($arr){return min(array_keys($arr));},$array));
    $width = $max - min(0,$min);

    foreach($array as &$sub){
        // $addin = array_diff_key(array_fill(0,$max,null),$sub);
        // $addin changed for negative keys:
        $addin = array_diff_key(array_combine(range($min,$max),array_fill(0,$width,null)),$sub);
        $sub = $addin + $sub;
        ksort($sub);
    }
    $order = array_flip($order);
    $params[] = $array[$by];
    foreach($params[0] as &$v) $v = $order[$v];
    foreach($array as &$v) $params[] = &$v; unset($v);
    call_user_func_array('array_multisort', $params);
    //no closeures here:
    //foreach($array as &$sub) $sub = array_filter(function($a){return !is_null($a);},$sub);
    $filter = create_function('$a','return !is_null($a);');
    foreach($array as &$sub) $sub = array_filter($sub,$filter);
    return $array;
}

【讨论】:

  • 是的,伙计,我想到了。我做了codepad.org/4QcAoemv,但实际上并没有将键添加到原始数组中。此外,有没有办法在进行多重排序后摆脱那些“空”值?
  • 呃,键盘正在运行 codepad.org/5kMHlRc6
  • 是的,可以完成这项工作。如果您可以检查我尝试使用更简单的方法来填充缺少的键foreach ($array['type'] as $k => $v) { foreach($array as $element => $a) { $iterator = $array[$element]; if(!isset($iterator[$k])){ $iterator[$key] = ''; } } } 的代码。这是临时填充 $iterator 数组而不是原始数组。再次感谢您的帮助,我将使用您的解决方案。我将其标记为正确。你能编辑你的答案吗?
  • 在最终函数中编辑。
  • 好了,我希望你明白,如果有错误,请随时编辑解决方案,我走了;)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-05
  • 2015-11-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-24
相关资源
最近更新 更多