Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/264.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 如何按列值分组子阵列?_Php_Arrays_Grouping - Fatal编程技术网

Php 如何按列值分组子阵列?

Php 如何按列值分组子阵列?,php,arrays,grouping,Php,Arrays,Grouping,我有以下数组 Array ( [0] => Array ( [id] => 96 [shipping_no] => 212755-1 [part_no] => reterty [description] => tyrfyt [packaging_type] => PC ) [1] =>

我有以下数组

Array
(
    [0] => Array
        (
            [id] => 96
            [shipping_no] => 212755-1
            [part_no] => reterty
            [description] => tyrfyt
            [packaging_type] => PC
        )

    [1] => Array
        (
            [id] => 96
            [shipping_no] => 212755-1
            [part_no] => dftgtryh
            [description] => dfhgfyh
            [packaging_type] => PC
        )

    [2] => Array
        (
            [id] => 97
            [shipping_no] => 212755-2
            [part_no] => ZeoDark
            [description] => s%c%s%c%s
            [packaging_type] => PC
        )

)
如何按
id
对阵列进行分组?是否有任何本机php函数可用于执行此操作

虽然这种方法可行,但我想使用
foreach
来实现这一点,因为使用上面的方法,我会得到重复的项目,这是我试图避免的


在上面的示例中,
id
有2项,因此它必须位于
id
的内部,您可以尝试以下操作:

$arr = array();

foreach($old_arr as $key => $item)
{
   $arr[$item['id']][$key] = $item;
}

ksort($arr, SORT_NUMERIC);
$group = array();

foreach ( $array as $value ) {
    $group[$value['id']][] = $value;
}

var_dump($group);
输出:

array
  96 => 
    array
      0 => 
        array
          'id' => int 96
          'shipping_no' => string '212755-1' (length=8)
          'part_no' => string 'reterty' (length=7)
          'description' => string 'tyrfyt' (length=6)
          'packaging_type' => string 'PC' (length=2)
      1 => 
        array
          'id' => int 96
          'shipping_no' => string '212755-1' (length=8)
          'part_no' => string 'dftgtryh' (length=8)
          'description' => string 'dfhgfyh' (length=7)
          'packaging_type' => string 'PC' (length=2)
  97 => 
    array
      0 => 
        array
          'id' => int 97
          'shipping_no' => string '212755-2' (length=8)
          'part_no' => string 'ZeoDark' (length=7)
          'description' => string 's%c%s%c%s' (length=9)
          'packaging_type' => string 'PC' (length=2)

没有本机版本,只需使用循环即可

$result=array();
foreach($data作为$element){
$result[$element['id'][]=$element;
}
用于($i=0;$i
扩展@baba的答案,我喜欢,但创建了一个更复杂的三层深多维(数组(数组)):

$group=array();
foreach($array作为$value){
$group[$value['id'][]=$value;
}
//仅从id 96输出数据
foreach($key=>$value的组){//outer循环
foreach($k=>$v)的值{//内部循环
if($key==96){//如果外循环等于96(可以是变量)

对于($i=0;$i),我只是从.NET LINQ的灵感出发,将其组合在一起

<?php

// callable type hint may be "closure" type hint instead, depending on php version
function array_group_by(array $arr, callable $key_selector) {
  $result = array();
  foreach ($arr as $i) {
    $key = call_user_func($key_selector, $i);
    $result[$key][] = $i;
  }  
  return $result;
}

 $data = array(
        array(1, "Andy", "PHP"),
        array(1, "Andy", "C#"),
        array(2, "Josh", "C#"),
        array(2, "Josh", "ASP"),
        array(1, "Andy", "SQL"),
        array(3, "Steve", "SQL"),
    );

$grouped = array_group_by($data, function($i){  return $i[0]; });

var_dump($grouped);

?>

LINQ很简单,它在PHP中的几个库中实现,包括*。它允许对数组和对象执行类似SQL的查询。
groubBy
函数专门用于分组,您只需指定要分组的字段:

$grouped_array = from($array)->groupBy('$v["id"]')->toArray();
其中,
'$v[“id”]
是此库支持的
函数($v){return$v[“id”];}
的缩写

结果将与接受的答案完全相同,只是代码更少

*由我开发

此功能可实现您所需的功能:

$grouped = array_group_by($arr, 'id');
它甚至支持多级分组:

$grouped = array_group_by($arr, 'id', 'part_no');

这将对关联数组进行分组 按国家划分的Ejm组

function getGroupedArray($array, $keyFieldsToGroup) {   
    $newArray = array();

    foreach ($array as $record) 
        $newArray = getRecursiveArray($record, $keyFieldsToGroup, $newArray);

    return $newArray;
}
function getRecursiveArray($itemArray, $keys, $newArray) {
    if (count($keys) > 1) 
        $newArray[$itemArray[$keys[0]]] = getRecursiveArray($itemArray,    array_splice($keys, 1), $newArray[$itemArray[$keys[0]]]);
    else
        $newArray[$itemArray[$keys[0]]][] = $itemArray;

    return $newArray;
}

$countries = array(array('Country'=>'USA', 'State'=>'California'),
                   array('Country'=>'USA', 'State'=>'Alabama'),
                   array('Country'=>'BRA', 'State'=>'Sao Paulo'));

$grouped = getGroupedArray($countries, array('Country'));
从以下位置检查功能:


1.
GROUP BY
one key

此函数作为数组的
分组依据
,但有一个重要限制:只能有一个分组“列”(
$identifier

function arrayUniqueByIdentifier(array $array, string $identifier)
{
    $ids = array_column($array, $identifier);
    $ids = array_unique($ids);
    $array = array_filter($array,
        function ($key, $value) use($ids) {
            return in_array($value, array_keys($ids));
        }, ARRAY_FILTER_USE_BOTH);
    return $array;
}

2.检测表的唯一行(二维数组)

此函数用于过滤“行”。如果我们说,二维数组是一个表,那么它的每个元素都是一行。因此,我们可以使用此函数删除重复的行。如果两行(第一维度的元素)的所有列(第二维度的元素)都相等,则两行(第一维度的元素)相等。与“列”的比较值适用:如果值是简单值,则将在比较时使用值本身;否则将使用其类型(
数组
对象
资源
未知类型

该策略很简单:从原始数组创建一个浅数组,其中元素是原始数组的
内爆
d“列”;然后在其上应用
array\u unique(…)
;最后使用检测到的ID对原始数组进行过滤

function arrayUniqueByRow(array $table = [], string $implodeSeparator)
{
    $elementStrings = [];
    foreach ($table as $row) {
        // To avoid notices like "Array to string conversion".
        $elementPreparedForImplode = array_map(
            function ($field) {
                $valueType = gettype($field);
                $simpleTypes = ['boolean', 'integer', 'double', 'float', 'string', 'NULL'];
                $field = in_array($valueType, $simpleTypes) ? $field : $valueType;
                return $field;
            }, $row
        );
        $elementStrings[] = implode($implodeSeparator, $elementPreparedForImplode);
    }
    $elementStringsUnique = array_unique($elementStrings);
    $table = array_intersect_key($table, $elementStringsUnique);
    return $table;
}
如果“column”值的类型是
object
,则还可以改进比较,检测“column”值的类

$infraodeseparator
应该或多或少复杂,z.B.
spl\u object\u hash($this)


3.检测具有表唯一标识符列的行(二维数组)

此解决方案依赖于第二个。现在完整的“行”不需要是唯一的。如果一个“行”的所有相关“字段”(第二维度的元素)与相应的“字段”(具有相同键的元素)相等,则两个“行”(第一维度的元素)现在相等

“相关”字段是“字段”(第二维度的元素),其键等于传递的“标识符”的元素之一


}

使用并缓存要分组的列值,然后将剩余数据作为在结果中创建的组的新子数组推送

function array_group(array $data, $by_column)
{
    $result = [];
    foreach ($data as $item) {
        $column = $item[$by_column];
        unset($item[$by_column]);
        $result[$column][] = $item;
    }
    return $result;
}

在功能性更强的编程风格中,您可以使用

$groupedById=array\u reduce($data,function)(数组$累加器,数组$元素){
$acculator[$element['id'][]=$element;
返回$累加器;
}, []);
试试这个功能

groupeByPHP($yourArray,'id',array('desc'=>array('part_no','packaging_type')),array('id','shipping_no')) 
$arr=数据平均值

$fldName=按列名称分组

function array_group_by( $arr, $fldName) {
    $groups = array();
    foreach ($arr as $rec) {
        $groups[$rec[$fldName]] = $rec;
    }
    return $groups;
}

function object_group_by( $obj, $fldName) {
    $groups = array();
    foreach ($obj as $rec) {
        $groups[$rec->$fldName] = $rec;
    }
    return $groups;
}
递归函数按键从头到尾分组二维数组

输入:

输出:

array
  96 => 
    array
      0 => 
        array
          'id' => int 96
          'shipping_no' => string '212755-1' (length=8)
          'part_no' => string 'reterty' (length=7)
          'description' => string 'tyrfyt' (length=6)
          'packaging_type' => string 'PC' (length=2)
      1 => 
        array
          'id' => int 96
          'shipping_no' => string '212755-1' (length=8)
          'part_no' => string 'dftgtryh' (length=8)
          'description' => string 'dfhgfyh' (length=7)
          'packaging_type' => string 'PC' (length=2)
  97 => 
    array
      0 => 
        array
          'id' => int 97
          'shipping_no' => string '212755-2' (length=8)
          'part_no' => string 'ZeoDark' (length=7)
          'description' => string 's%c%s%c%s' (length=9)
          'packaging_type' => string 'PC' (length=2)
代码:

函数数组按键分组(&$arr,$keys){
如果(计数($arr)<2){
$arr=数组移位($arr[0]);
返回;
}
foreach($arr as$k=>$item){
$fvalue=数组\移位($item);
$arr[$fvalue][]=$item;
未结算($arr[$k]);
}
数组移位($键);
foreach($arr as和$sub_arr){
数组按键分组($sub\u arr,$keys);
}
}

我认为这在PHP5.5中效果更好+

$IdVar = array_column($data, 'id');

请注意,_首先我需要操作数组?然后再操作foreach以达到真正的目的?是否还要删除重复项???大多数解决方案使用一个foreach。@JustinJohn大多数解决方案使用一个foreach创建数组,最终结果不是数组。我正在寻找更好的解决方案。你的意思是最终结果不是一维的l数组。我的意思是..我需要对创建的数组进行预处理,以将其转换为html元素的值。你能给我一个如何按多个字段分组的提示吗?在我的用例中,我有一个带有日期字段的对象,需要按年、月和日期对其进行分组。类似于{2016=>{09=>{15=>$object}}@fnagel嵌套分组有点复杂。请参阅。它包括一个助手函数
groupby\u multiple
,以及嵌套分组工作原理的详细说明。使用此函数,您的查询将看起来像
groupby\u multiple($objects,['$v->date->format(“Y”),'$v->date
function array_group_by($arr, array $keys) {

if (!is_array($arr)) {
    trigger_error('array_group_by(): The first argument should be an array', E_USER_ERROR);
}
if (count($keys)==0) {
    trigger_error('array_group_by(): The Second argument Array can not be empty', E_USER_ERROR);
}

// Load the new array, splitting by the target key
$grouped = [];
foreach ($arr as $value) {
    $grouped[$value[$keys[0]]][] = $value;
}

// Recursively build a nested grouping if more parameters are supplied
// Each grouped array value is grouped according to the next sequential key
if (count($keys) > 1) {
        foreach ($grouped as $key => $value) {
       $parms = array_merge([$value], [array_slice($keys, 1,count($keys))]);
       $grouped[$key] = call_user_func_array('array_group_by', $parms);

    }
}
return $grouped;
function array_group(array $data, $by_column)
{
    $result = [];
    foreach ($data as $item) {
        $column = $item[$by_column];
        unset($item[$by_column]);
        $result[$column][] = $item;
    }
    return $result;
}
function groupeByPHP($array,$indexUnique,$assoGroup,$keepInOne){
$retour = array();
$id = $array[0][$indexUnique];
foreach ($keepInOne as $keep){
    $retour[$id][$keep] = $array[0][$keep];
}
foreach ($assoGroup as $cle=>$arrayKey){
    $arrayGrouped = array();
        foreach ($array as $data){
            if($data[$indexUnique] != $id){
                $id = $data[$indexUnique];
                foreach ($keepInOne as $keep){
                    $retour[$id][$keep] = $data[$keep];
                }
            }
            foreach ($arrayKey as $val){
                $arrayGrouped[$val] = $data[$val];
            }
            $retour[$id][$cle][] = $arrayGrouped;
            $retour[$id][$cle] = array_unique($retour[$id][$cle],SORT_REGULAR);
        }
}
return  $retour;
}
groupeByPHP($yourArray,'id',array('desc'=>array('part_no','packaging_type')),array('id','shipping_no')) 
function array_group_by( $arr, $fldName) {
    $groups = array();
    foreach ($arr as $rec) {
        $groups[$rec[$fldName]] = $rec;
    }
    return $groups;
}

function object_group_by( $obj, $fldName) {
    $groups = array();
    foreach ($obj as $rec) {
        $groups[$rec->$fldName] = $rec;
    }
    return $groups;
}
$arr = array(
    '0' => array(
        'key0' => 'value0',
        'key1' => 'value1',
        'key2' => 'value02',
    ),
    '2' => array(
        'key0' => 'value0',
        'key1' => 'value1',
        'key2' => 'value12',
    ),
    '3' => array(
        'key0' => 'value0',
        'key1' => 'value3',
        'key2' => 'value22',
    ),
);
$keys = array('key0', 'key1', 'key2');
$arr = array(
    'value0' => array(
        'value1 => array(
            'value02' => null,
            'value12' => null,
        ),
        'value3' => 'value22',
    ),
);
function array_group_by_keys(&$arr, $keys) {

    if (count($arr) < 2){
        $arr = array_shift($arr[0]);
        return;
    }

    foreach ($arr as $k => $item) {
        $fvalue = array_shift($item);
        $arr[$fvalue][] = $item;
        unset($arr[$k]);
    }

    array_shift($keys);
    foreach ($arr as &$sub_arr) {
        array_group_by_keys($sub_arr, $keys);
    }
}
$IdVar = array_column($data, 'id');