서브어레이를 열 값으로 그룹화하려면 어떻게 해야 합니까?
다음과 같은 어레이가 있습니다.
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
네이티브는 없습니다.루프만 사용하세요.
$result = array();
foreach ($data as $element) {
$result[$element['id']][] = $element;
}
다음을 시도할 수 있습니다.
$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)
보다 기능적인 프로그래밍 스타일에서는
$groupedById = array_reduce($data, function (array $accumulator, array $element) {
$accumulator[$element['id']][] = $element;
return $accumulator;
}, []);
나는 단지 영감을 받아 이것을 조립했다.네트워크 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 array_group(array $data, $by_column)
{
$result = [];
foreach ($data as $item) {
$column = $item[$by_column];
unset($item[$by_column]);
$result[$column][] = $item;
}
return $result;
}
완전한 테스트를 포함한 Composer 대체 기능을 원하는 경우 array_group_by 함수가 원하는 기능을 수행합니다.완전 공개:저는 그 도서관의 저자예요.
$grouped = array_group_by($arr, 'id');
또, 멀티 레벨의 그룹화, 또는 커스텀콜백 함수를 사용한 복잡한 그룹화도 서포트하고 있습니다.
// Multilevel grouping
$grouped = array_group_by($arr, 'id', 'part_no');
// Grouping by a callback/callable function
$grouped = array_group_by($records, function ($row) {
return $row->city;
});
$arr = Data Araay;
$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;
}
$arr = array();
foreach($old_arr as $key => $item)
{
$arr[$item['id']][$key] = $item;
}
ksort($arr, SORT_NUMERIC);
for($i = 0 ; $i < count($arr) ; $i++ )
{
$tmpArr[$arr[$i]['id']] = $arr[$i]['id'];
}
$vmpArr = array_keys($tmpArr);
print_r($vmpArr);
마음에 드는 @baba의 답변을 확장하여 보다 복잡한 3레벨의 심층 다차원(array(array(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은 부품번호와 배송번호가 212755-1입니다.
96의 부품번호는 dftgtryh이고 배송번호는 212755-1입니다.
YaLinqo*를 포함한 여러 라이브러리의 PHP에 구현되어 있는 LINQ를 사용하는 것은 간단한 일입니다.어레이 및 개체에 대해 SQL과 같은 쿼리를 수행할 수 있습니다.그groubBy
함수는 그룹화를 위해 특별히 설계되었습니다.그룹화할 필드를 지정하기만 하면 됩니다.
$grouped_array = from($array)->groupBy('$v["id"]')->toArray();
어디에'$v["id"]'
의 줄임말이다function ($v) { return $v["id"]; }
이 라이브러리는 이를 지원합니다.
결과는 코드만 줄이면 승인된 답변과 동일합니다.
* 내가 개발한
1. GROUP BY
원키
이 함수는 다음과 같이 동작합니다.GROUP BY
단, 중요한 한 가지 제한이 있습니다.그룹 "컬럼"은 1개뿐입니다.($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. 표의 고유행 검출(2차원 배열)
이 기능은 "행" 필터링을 위한 것입니다.2차원 배열을 표라고 하면 각 요소는 행입니다.이 기능으로 중복된 행을 제거할 수 있습니다.두 행(첫 번째 차원의 요소)은 모든 열(두 번째 차원의 요소)이 동일한 경우 동일합니다."column" 값 합계에 적용되는 경우:값이 단순한 유형일 경우 값 자체가 비교에 사용됩니다. 그렇지 않을 경우 해당 유형(array
,object
,resource
,unknown type
가 사용됩니다.
배열을 는 elements략은은간간간간간,,,,,,,,입니다.이치노요소는implode
의 d 후 d "d"를 적용합니다.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;
}
'가 '열'일 ' 값의 .object
.
$implodeSeparator
. should z 、 z.B.spl_object_hash($this)
.
3. 표의 고유 식별자 열이 있는 행 검출(2차원 배열)
이 솔루션은 두 번째 솔루션에 의존합니다.이제 완전한 "행"이 고유할 필요가 없습니다.한 행의 모든 관련 "필드"(두 번째 차원의 요소)가 이에 따른 "필드"(같은 키를 가진 요소)와 동일한 경우, 두 개의 "행"(첫 번째 차원의 요소)은 이제 동일합니다.
"관련" "필드"는 전달된 "식별자"의 요소 중 하나에 해당하는 키를 가진 "필드"(두 번째 차원의 요소)입니다.
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;
}
국가별로 관련 어레이 Ejm Group을 그룹화합니다.
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'));
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;
}
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'))
키별로 2차원 배열을 그룹화하는 재귀 함수
입력:
$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);
}
}
쉽게 그룹화할 수 있습니다.배열내의 임의의 「키」로 그룹화할 수 있습니다.
$data = [
[
"id" => 96,
"shipping_no" => "212755-1",
"part_no" => "reterty",
"description" => "tyrfyt",
"packaging_type" => "PC"
],
[
"id" => 96,
"shipping_no" => "212755-1",
"part_no" => "dftgtryh",
"description" => "dfhgfyh",
"packaging_type" => "PC"
],
[
"id" => 97,
"shipping_no" => "212755-2",
"part_no" => "ZeoDark",
"description" => "s%c%s%c%s",
"packaging_type" => "PC"
]
];
function groupBy($array, $key) {
$groupedData = [];
$data = [];
$_id = "";
for ($i=0; $i < count($array); $i++) {
$row = $array[$i];
if($row[$key] != $_id){
if(count($data) > 0){
$groupedData[] = $data;
}
$_id = $row[$key];
$data = [
$key => $_id
];
}
unset($row[$key]);
$data["data"][] = $row;
if($i == count($array) - 1){
$groupedData[] = $data;
}
}
return $groupedData;
}
print_r(groupBy($data, "id"));
결과는 다음과 같습니다.
Array
(
[0] => Array
(
[id] => 96
[data] => Array
(
[0] => Array
(
[shipping_no] => 212755-1
[part_no] => reterty
[description] => tyrfyt
[packaging_type] => PC
)
[1] => Array
(
[shipping_no] => 212755-1
[part_no] => dftgtryh
[description] => dfhgfyh
[packaging_type] => PC
)
)
)
[1] => Array
(
[id] => 97
[data] => Array
(
[0] => Array
(
[shipping_no] => 212755-2
[part_no] => ZeoDark
[description] => s%c%s%c%s
[packaging_type] => PC
)
)
)
)
"key" 파라미터를 변경하면 변경되지 않고 동작합니다.
print_r(groupBy($data, "shipping_no"));
Array
(
[0] => Array
(
[shipping_no] => 212755-1
[data] => Array
(
[0] => Array
(
[id] => 96
[part_no] => reterty
[description] => tyrfyt
[packaging_type] => PC
)
[1] => Array
(
[id] => 96
[part_no] => dftgtryh
[description] => dfhgfyh
[packaging_type] => PC
)
)
)
[1] => Array
(
[shipping_no] => 212755-2
[data] => Array
(
[0] => Array
(
[id] => 97
[part_no] => ZeoDark
[description] => s%c%s%c%s
[packaging_type] => PC
)
)
)
)
다단계 그룹화는 어떨까요?
데이터:
$rows = [
['country'=>'Japan', 'city'=>'Tokyo', 'surname'=>'Miyazaki', 'name'=>'Hayao'],
['country'=>'France', 'city'=>'Paris', 'surname'=>'Godard', 'name'=>'Jean-Luc'],
['country'=>'France', 'city'=>'Lyon', 'surname'=>'Godard', 'name'=>'Marguerite'],
['country'=>'Japan', 'city'=>'Tokyo', 'surname'=>'Miyazaki', 'name'=>'Akira'],
['country'=>'Japan', 'city'=>'Nara', 'surname'=>'Kurosawa', 'name'=>'Akira'],
['country'=>'France', 'city'=>'Paris', 'surname'=>'Duras', 'name'=>'Marguerite'],
];
$groups = groupBy($rows, 'country', 'city', 'surname');
코드:
function groupBy($rows, ...$keys)
{
if ($key = array_shift($keys)) {
$groups = array_reduce($rows, function ($groups, $row) use ($key) {
$group = is_object($row) ? $row->{$key} : $row[$key]; // object is available too.
$groups[$group][] = $row;
return $groups;
}, []);
if ($keys) {
foreach ($groups as $subKey=>$subRows) {
$groups[$subKey] = self::groupBy($subRows, ...$keys);
}
}
}
return $groups;
}
언급URL : https://stackoverflow.com/questions/12706359/how-to-group-subarrays-by-a-column-value
'programing' 카테고리의 다른 글
현재 날짜에서 일수를 뺀 Laravel Carbon (0) | 2022.10.29 |
---|---|
Python pip 설치 실패: 잘못된 명령 eg_info (0) | 2022.10.29 |
JavaScript에서 URL을 인코딩하시겠습니까? (0) | 2022.10.19 |
캡슐화된 익명 함수 구문 설명 (0) | 2022.10.19 |
RowDataPacket 객체에 액세스하는 방법 (0) | 2022.10.19 |