PHP数组组

我有以下数组

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分组数组? 有没有任何原生的PHPfunction可以做到这一点?

如果我foreach上面那么我会得到一个重复的,我怎样才能避免呢?

在上面的例子中id有2个项目,所以它需要在id里面。

编辑:一切工作都很好:但是有什么办法可以实现一个前进?

没有本地的,只是使用循环。

 $result = array(); foreach ($arr as $data) { $id = $data['id']; if (isset($result[$id])) { $result[$id][] = $data; } else { $result[$id] = array($data); } } 

您可以尝试以下方法:

 $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) 

我只是一起扔在一起,灵感来自.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); ?> 

瞧,你得到了

 array(3) { [1]=> array(3) { [0]=> array(3) { [0]=> int(1) [1]=> string(4) "Andy" [2]=> string(3) "PHP" } [1]=> array(3) { [0]=> int(1) [1]=> string(4) "Andy" [2]=> string(2) "C#" } [2]=> array(3) { [0]=> int(1) [1]=> string(4) "Andy" [2]=> string(3) "SQL" } } [2]=> array(2) { [0]=> array(3) { [0]=> int(2) [1]=> string(4) "Josh" [2]=> string(2) "C#" } [1]=> array(3) { [0]=> int(2) [1]=> string(4) "Josh" [2]=> string(3) "ASP" } } [3]=> array(1) { [0]=> array(3) { [0]=> int(3) [1]=> string(5) "Steve" [2]=> string(3) "SQL" } } } 

我也需要这样的function。 我创build了这个,你通过哪个列你想分组:

 function array_group(array $data, $by_column) { $result = []; foreach ($data as $item) { $column = $item[$by_column]; unset($item[$by_column]); if (isset($result[$column])) { $result[$column][] = $item; } else { $result[$column] = array($item); } } return $result; } 
 for($i = 0 ; $i < count($arr) ; $i++ ) { $tmpArr[$arr[$i]['id']] = $arr[$i]['id']; } $vmpArr = array_keys($tmpArr); print_r($vmpArr); 

这array_group_by函数实现你正在寻找的东西:

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

它甚至支持多级分组:

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

扩展@ baba的答案,我喜欢,但是创build了一个更复杂的三维深度多维(数组(arrays(数组))):

 $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有一个零件号。 保存和运输号码212755-1

96有一个零件号。 的dftgtryh和运输号码212755-1

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

 $grouped_array = from($array)->groupBy('$v["id"]')->toArray(); 

其中'$v["id"]'function ($v) { return $v["id"]; }的缩写function ($v) { return $v["id"]; } function ($v) { return $v["id"]; }这个库支持。

结果将会与接受的答案完全一样,只需less量代码。

*由我开发

1. GROUP BY一键

该函数作为GROUP BY用于数组,但有一个重要限制:只有一个分组“列”( $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.检测表(二维数组)的唯一行

此function用于过滤“行”。 如果我们说,一个二维数组是一个表,那么它的每个元素就是一行。 所以,我们可以用这个函数删除重复的行。 如果所有列(第二维的元素)相等,则两行(第一维的元素)是相等的。 对于“列”值的比较适用:如果值是简单types ,则值本身将用于比较; 否则将使用它的types( arrayobjectresourceunknown type )。

策略很简单:从原始数组中创build一个浅层数组,其中元素是原数组的内部“列”; 然后在其上应用array_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; } 

如果types是object ,也可以改进比较,检测“列”值的类。

$implodeSeparator应该或多或less复杂, spl_object_hash($this)


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

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

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

 function arrayUniqueByMultipleIdentifiers(array $table, array $identifiers, string $implodeSeparator = null) { $arrayForMakingUniqueByRow = $removeArrayColumns($table, $identifiers, true); $arrayUniqueByRow = $arrayUniqueByRow($arrayForMakingUniqueByRow, $implodeSeparator); $arrayUniqueByMultipleIdentifiers = array_intersect_key($table, $arrayUniqueByRow); return $arrayUniqueByMultipleIdentifiers; } function removeArrayColumns(array $table, array $columnNames, bool $isWhitelist = false) { foreach ($table as $rowKey => $row) { if (is_array($row)) { if ($isWhitelist) { foreach ($row as $fieldName => $fieldValue) { if (!in_array($fieldName, $columnNames)) { unset($table[$rowKey][$fieldName]); } } } else { foreach ($row as $fieldName => $fieldValue) { if (in_array($fieldName, $columnNames)) { unset($table[$rowKey][$fieldName]); } } } } } return $table; } 
 $arr = array(); foreach($old_arr as $key => $item) { $arr[$item['id']][$key] = $item; } ksort($arr, SORT_NUMERIC); 

这应该组合一个关联数组Ejm Group By Country

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

检查来自Nspl的 索引函数:

 use function \nspl\a\indexed; $grouped = indexed($data, 'id'); 
 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; 

}

在更多的函数式编程风格中,可以使用array_reduce

 $groupedById = array_reduce($data, function ($accumulator, $element) { if (!isset($accumulator[$element['id']])) { $accumulator[$element['id']] = []; } $accumulator[$element['id']][] = $element; return $accumulator; }, []);