如何按列值对子数组进行分组?

107
我有以下数组。
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内部。


你是否也想要删除重复的内容? - Baba
大多数解决方案都使用了一个FOREACH循环。 - Justin John
@JustinJohn 大多数解决方案都使用一个FOREACH来创建数组,但最终结果并不是一个数组。我正在寻找更好的解决方案。 - Red
1
你的意思是最终结果不是一维数组。 - Justin John
我的意思是,我需要使用foreach循环已创建的数组,将其转换为HTML元素值。 - Red
21个回答

2
$arr = array();

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

ksort($arr, SORT_NUMERIC);

请注意,首先我需要操作数组吗?然后再使用foreach进行实际目的吗? - Red

2
for($i = 0 ; $i < count($arr)  ; $i++ )
{
    $tmpArr[$arr[$i]['id']] = $arr[$i]['id'];
}
$vmpArr = array_keys($tmpArr);
print_r($vmpArr);

这个答案非常错误 - 它只返回键并会杀死重复项。 它还使用了每次迭代都调用count()的不好的实践。 仅包含代码的答案在SO上的价值很低。我可能永远不会理解为什么会有人点赞。 - mickmackusa

2

在@baba的回答基础上,我想进一步扩展,但这会创建一个更复杂的三层多维数组(array(array(array))):

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

// output only data from id 96
foreach ($group as $key=>$value) { //outer loop
 foreach ($value as $k=>$v){ //inner loop
  if($key==96){ //if outer loop is equal to 96 (could be variable)
   for ($i=0;$i<count($k);$i++){ //iterate over the inner loop
        printf($key.' has a part no. of '.$v['part_no'].' and shipping no. of '.$v['shipping_no'].'<br>');
   }
 }
}
 }

将输出:

96具有零件号为reterty和运输号为212755-1

96具有零件号为dftgtryh和运输号为212755-1


1
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')) 

1

请检查Nspl中的indexed函数:

use function \nspl\a\indexed;
$grouped = indexed($data, 'id');

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

}


1
递归函数按照从第一个到最后一个键将二维数组分组 输入:
$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');

Output:

$arr = array(
    'value0' => array(
        'value1 => array(
            'value02' => null,
            'value12' => null,
        ),
        'value3' => 'value22',
    ),
);

Code:

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

1

这应该是对关联数组进行分组的操作 例如按国家分组

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

0

当遇到唯一标识列值时,通过将引用变量推入结果数组中,您无需在分组后重新索引结果数组。

代码:(演示

$result = [];
foreach ($array as $row) {
    $key = $row['id'];  // assign the grouping column's value
    unset($row['id']);  // remove the grouping column from the row
    if (!isset($ref[$key])) {
        $ref[$key] = [$row];      // declare first entry as a subarray
        $result[] = &$ref[$key];  // push the reference variable into the result array
    } else {
        $ref[$key][] = $row; // add a child to the reference
    }
}
var_export($result);

0
array_combine() 怎么样? 使用 array_combine() 将每一行存储在 $groupByColumn 的索引上,因此我们可以将 $groupByColumn 用作键。这将返回每个组的最后一行(array_combine() 在键已经存在时会覆盖该值 - 参见 https://www.php.net/manual/en/function.array-combine.php#111668)。如果您想返回第一行或某些特定行,则可以尝试使用 array_reverse() 或 usort() 等函数进行操作。
$result = array_combine(
    array_column($source, $groupByColumn),
    $source
);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接