PHP按数组对数组进行分组

时间:2013-03-05 10:44:16

标签: php arrays sorting grouping multidimensional-array

嗨,我有一点问题,我似乎无法找到答案。我有一个包含数组的数组,并希望根据字段的相同值将这些子数组分组。这是我的代码,允许我根据值内的数组对数组进行排序。如何根据共享值对结果进行分组?我可能不会知道所有的值,因为有些是基于日期的,我希望例如每天/每月组合

if($filter == "ORDER BY TODO_REF DESC"){
$type_sort = 0;
};
if($filter == "ORDER BY TODO_PRIO DESC"){
$type_sort = 2;
};
if($filter == "ORDER BY TODO_DEAD DESC"){
$type_sort = 3;
};

function aasort (&$array, $key) {
$sorter=array();
$ret=array();
reset($array);
foreach ($array as $ii => $va) {
    $sorter[$ii]=$va[$key];
}
asort($sorter);
foreach ($sorter as $ii => $va) {
    $ret[$ii]=$array[$ii];
}
$array=$ret;
}

 aasort($test_array, $type_sort);
print_r($test_array);

当前输出:

priority
Array
 (

[3] => Array
    (
        [0] => 2
        [1] => sdfsdgdfgdfgdfg
        [2] => 3
        [3] => 2013-05-30 13:53:23
    )

[2] => Array
    (
        [0] => 1
        [1] => This must also be done
        [2] => 4
        [3] => 2013-03-28 12:13:34
    )

[1] => Array
    (
        [0] => 1
        [1] => testing this show me 2
        [2] => 5
        [3] => 2029-02-23 17:27:20
    )

[0] => Array
    (
        [0] => 1
        [1] => Do this task and make sure it gets done
        [2] => 5
        [3] => 2013-06-28 12:12:41
    )

)

我想要的是这样的东西,它们被分成基于子数组键2的单独数组:

Array
(
[3] => Array
    (
        [0] => 2
        [1] => sdfsdgdfgdfgdfg
        [2] => 3
        [3] => 2013-05-30 13:53:23
    )

)
Array
(
[2] => Array
    (
        [0] => 1
        [1] => This must also be done
        [2] => 4
        [3] => 2013-03-28 12:13:34
    )

)
Array
(
[1] => Array
    (
        [0] => 1
        [1] => testing this show me 2
        [2] => 5
        [3] => 2029-02-23 17:27:20
    )

[0] => Array
    (
        [0] => 1
        [1] => Do this task and make sure it gets done
        [2] => 5
        [3] => 2013-06-28 12:12:41
    )

)

3 个答案:

答案 0 :(得分:0)

$array_1 = array();
$array_2 = array();
foreach($test_array as $item) {
  if($item[0] == 1) {
    $array_1[] = $item;
  } elseif($item[0] == 2) {
    $array_2[] = $item;
  }
}
$final_array = array($array_1, $array_2);

必须有更优化的代码,但这应该满足您的需求。

答案 1 :(得分:0)

array_multisort()就是你之后它允许你按子数组排序主数组并保持键值链接

我使用下面的代码在具有许多列和可排序列的表上排序基于排序顺序箭头asc / desc的相当大的多维数组。它变得一团糟,但你应该能够遵循它。

if (strlen($_GET['col'])<1) {
                foreach ($dataarray as $key => $row) {
                    $spend[$key]  = $row[6];
                }
                array_multisort($spend, SORT_DESC, $dataarray);
            } else if ($_GET['col']=="spend"){
                foreach ($dataarray as $key => $row) {
                    $spend[$key]  = $row[3];
                }
                if ($_GET['order']=="asc") {
                    array_multisort($spend, SORT_ASC, $dataarray);
                } else {
                    array_multisort($spend, SORT_DESC, $dataarray);
                }
            } else if ($_GET['col']=="name"){
                foreach ($dataarray as $key => $row) {
                    $name[$key]  = $row[1];
                }
                if ($_GET['order']=="asc") {
                    array_multisort($name, SORT_ASC, $dataarray);
                } else {
                    array_multisort($name, SORT_DESC, $dataarray);
                }
            } else if ($_GET['col']=="avg"){
                foreach ($dataarray as $key => $row) {
                    $avg[$key]  = $row[4];
                }
                if ($_GET['order']=="asc") {
                    array_multisort($avg, SORT_ASC, $dataarray);
                } else {
                    array_multisort($avg, SORT_DESC, $dataarray);
                }
            } else if ($_GET['col']=="sites"){
                foreach ($dataarray as $key => $row) {
                    $sites[$key]  = $row[5];
                }
                if ($_GET['order']=="asc") {
                    array_multisort($sites, SORT_ASC, $dataarray);
                } else {
                    array_multisort($sites, SORT_DESC, $dataarray);
                }
            } else if ($_GET['col']=="rate"){
                foreach ($dataarray as $key => $row) {
                    $rate[$key]  = $row[6];
                }
                if ($_GET['order']=="asc") {
                    array_multisort($rate, SORT_ASC, $dataarray);
                } else {
                    array_multisort($rate, SORT_DESC, $dataarray);
                }
            } else {
                foreach ($dataarray as $key => $row) {
                    $spend[$key]  = $row[2];
                }
                array_multisort($spend, SORT_DESC, $dataarray);
            }

答案 2 :(得分:0)

  1. 我总是建议使用一个查找数组,然后快速调用if-elseif-elseif-elseif...else,而不是用一组isset()条件来确定排序/分组列。我发现此语法更简洁,更易读且易于维护。
  2. 为使分组数据得到正确排序,请提前对数据进行排序(尽管它仍处于较简单的形式)。 usort()与飞船操作员(php7)一起为您完成所有艰苦的工作。只需确保将$groupsort变量通过use传递到函数范围即可。
  3. 在迭代输入数组时,隔离标识列的值(并根据需要对其进行准备),然后将其用作临时键来确定应存储$row数据的组。
  4. 最后,使用array_values()删除临时标识密钥(如果需要)。

代码:(Demo

$filter = "ORDER BY TODO_PRIO DESC";
$lookup = [
    "ORDER BY TODO_REF DESC" => 0,
    "ORDER BY TODO_PRIO DESC" => 2,
    "ORDER BY TODO_DEAD DESC" => 3
];
$groupsort = isset($lookup[$filter]) ? $lookup[$filter] : 0;  

$array = [
    [1, "Do this task and make sure it gets done", 5, "2013-06-28 12:12:41"],
    [1, "testing this show me 2", 5, "2029-02-23 17:27:20"],
    [1, "This must also be done", 4, "2013-03-28 12:13:34"],
    [2, "sdfsdgdfgdfgdfg", 3, "2013-05-30 13:53:23"],
    [2, "Another priority", 3, "2013-03-28 11:11:11"]
];

// sort DESC on $groupsort column values
usort($array, function($a, $b)use($groupsort) { return $b[$groupsort] <=> $a[$groupsort]; }); 

// group by $groupsort column values
foreach ($array as $row) {
    $id = $row[$groupsort];                             // just to improve readability
    if ($groupsort == 3) { $id = substr($id, 0, 10); }  // remove time from datetime stamp
    $result[$id][] = $row;                              // store the current value
}

var_export(array_values($result));                      // reindex first level (remove temp keys);

输出:

array (
  0 => 
  array (
    0 => 
    array (
      0 => 1,
      1 => 'Do this task and make sure it gets done',
      2 => 5,
      3 => '2013-06-28 12:12:41',
    ),
    1 => 
    array (
      0 => 1,
      1 => 'testing this show me 2',
      2 => 5,
      3 => '2029-02-23 17:27:20',
    ),
  ),
  1 => 
  array (
    0 => 
    array (
      0 => 1,
      1 => 'This must also be done',
      2 => 4,
      3 => '2013-03-28 12:13:34',
    ),
  ),
  2 => 
  array (
    0 => 
    array (
      0 => 2,
      1 => 'sdfsdgdfgdfgdfg',
      2 => 3,
      3 => '2013-05-30 13:53:23',
    ),
    1 => 
    array (
      0 => 2,
      1 => 'Another priority',
      2 => 3,
      3 => '2013-03-28 11:11:11',
    ),
  ),
)