我正在尝试按值对数组进行分组。下面是我的数组:
$array = Array ( 0 => Array ( 'name' => 'John Doe', 'age' => '36', 'code' => '437', 'group' => '1000', ), 1 => Array ( 'name' => 'John Doe', 'age' => '36', 'code' => '437', 'group' => '7777', ), 2 => Array ( 'name' => 'John Doe', 'age' => '36', 'code' => '437', 'group' => '7777', ), 3 => Array ( 'name' => 'John Doe', 'age' => '36', 'code' => '437', 'group' => '4000', ), 4 => Array ( 'name' => 'John Doe', 'age' => '36', 'code' => '437', 'group' => '4000', ), 5 => Array ( 'name' => 'John Doe', 'age' => '36', 'code' => '437', 'group' => '5000', ), 6 => Array ( 'name' => 'John Doe', 'age' => '36', 'code' => '437', 'group' => '6000', ), 7 => Array ( 'name' => 'John Doe', 'age' => '36', 'code' => '437', 'group' => '6000', ), );
我在下面尝试过
$result = array();
foreach ($array as $key => $record) {
if (!isset($result[$record['code']])) {
$result[$record['code']] = array(
'name' => $record['name'],
'age' => $record['age'],
'groups' => array(array($record['code'], $record['group'])),
);
}
else {
$result[$record['code']]['groups'][] = array($record['code'],$record['group']);
}
}
$result = array_values($result);
print_r($result);
我得到了:
Array ( [0] => Array ( [name] => John Doe [age] => 36 [groups] => Array ( [0] => Array ( [0] => 437 [1] => 1000 ) [1] => Array ( [0] => 437 [1] => 7777 ) [2] => Array ( [0] => 437 [1] => 7777 ) [3] => Array ( [0] => 437 [1] => 4000 ) [4] => Array ( [0] => 437 [1] => 4000 ) [5] => Array ( [0] => 437 [1] => 5000 ) [6] => Array ( [0] => 437 [1] => 6000 ) [7] => Array ( [0] => 437 [1] => 6000 ) ) ) )
现在,我希望将数组按组7777、1000和其他(所有其他组值)的值进行分组:
Array ( [0] => Array ( [name] => John Doe [age] => 36 [7777] => Array ( [0] => Array ( [0] => 437 [1] => 7777 ) [1] => Array ( [0] => 437 [1] => 7777 ) ) [6000] => Array ( [0] => Array ( [0] => 437 [1] => 6000 ) [1] => Array ( [0] => 437 [1] => 6000 ) ) [others] => Array ( [0] => Array ( [0] => 437 [1] => 1000 ) [1] => Array ( [0] => 437 [1] => 4000 ) [2] => Array ( [0] => 437 [1] => 4000 ) [3] => Array ( [0] => 437 [1] => 5000 ) ) ) )
谢谢。
答案 0 :(得分:1)
我不确定您的业务逻辑是什么,但是您的数据存储设计不是最佳的。冗余级别和值可以并且应该作为最佳实践而删除。除了这些建议,如果您的输入数组未按code
值进行预排序并且您拥有多个code
值,那么Mickael的解决方案可能会让您失望。
该过程非常简单。将code
值用作输出数组中的临时唯一键。如果处理第一次出现的code
值,请设置name
和age
元素。每次迭代时,都根据code
值和group
值条件向输出数组添加一个新的子数组。循环结束后,用array_values()
重新索引输出数组。
代码:(Demo)
$array = [
['name' => 'John Doe', 'age' => '36', 'code' => '437', 'group' => '1000'],
['name' => 'John Doe', 'age' => '36', 'code' => '437', 'group' => '7777'],
['name' => 'John Doe', 'age' => '36', 'code' => '437', 'group' => '7777'],
['name' => 'John Doe', 'age' => '36', 'code' => '437', 'group' => '4000'],
['name' => 'John Doe', 'age' => '36', 'code' => '437', 'group' => '4000'],
['name' => 'John Doe', 'age' => '36', 'code' => '437', 'group' => '5000'],
['name' => 'John Doe', 'age' => '36', 'code' => '437', 'group' => '6000'],
['name' => 'John Doe', 'age' => '36', 'code' => '437', 'group' => '6000']
];
foreach ($array as $row) {
if (!isset($result[$row['code']])) {
$result[$row['code']] = ['name' => $row['name'], 'age' => $row['age']];
}
$result[$row['code']][in_array($row['group'], ['7777','6000']) ? $row['group'] : 'others'][] = [$row['code'], $row['group']];
}
var_export(array_values($result));
输出:
array (
0 =>
array (
'name' => 'John Doe',
'age' => '36',
'others' =>
array (
0 =>
array (
0 => '437',
1 => '1000',
),
1 =>
array (
0 => '437',
1 => '4000',
),
2 =>
array (
0 => '437',
1 => '4000',
),
3 =>
array (
0 => '437',
1 => '5000',
),
),
7777 =>
array (
0 =>
array (
0 => '437',
1 => '7777',
),
1 =>
array (
0 => '437',
1 => '7777',
),
),
6000 =>
array (
0 =>
array (
0 => '437',
1 => '6000',
),
1 =>
array (
0 => '437',
1 => '6000',
),
),
),
)
答案 1 :(得分:0)
尝试一下:
// Create a new array
$result = array();
// Loop through your array
foreach ($array as $value) {
// Create a key that start at 0
$i = 0;
// Test if $result[0] exist : if yes, you have data, else you have nothing
if (isset($result[$i])) {
do {
// Check if the 'name' is new : if yes, $i++ to check next name
if ($result[$i]['name'] !== $value['name']) $i++;
// If you find similar name, stop here
else break;
} while (isset($result[$i]));
// Just add $result[0] with name and age value
} else {
$result[$i] = array (
'name' => $value['name'],
'age' => $value['age']
);
}
// Now you know the index of result you need to work with
// Just add a new code / group array to your code index
$result[$i][$value['group']][] = array($value['code'], $value['group']);
}
如果您执行var_dump($result);
,则输出为:
array (size=1)
0 =>
array (size=7)
'name' => string 'John Doe' (length=8)
'age' => string '36' (length=2)
1000 =>
array (size=1)
0 =>
array (size=2)
0 => string '437' (length=3)
1 => string '1000' (length=4)
7777 =>
array (size=2)
0 =>
array (size=2)
0 => string '437' (length=3)
1 => string '7777' (length=4)
1 =>
array (size=2)
0 => string '437' (length=3)
1 => string '7777' (length=4)
4000 =>
array (size=2)
0 =>
array (size=2)
0 => string '437' (length=3)
1 => string '4000' (length=4)
1 =>
array (size=2)
0 => string '437' (length=3)
1 => string '4000' (length=4)
5000 =>
array (size=1)
0 =>
array (size=2)
0 => string '437' (length=3)
1 => string '5000' (length=4)
6000 =>
array (size=2)
0 =>
array (size=2)
0 => string '437' (length=3)
1 => string '6000' (length=4)
1 =>
array (size=2)
0 => string '437' (length=3)
1 => string '6000' (length=4)
编辑:
要仅获取等于7777
和6000
的组值,请替换
$result[$i][$value['group']][] = array($value['code'], $value['group']);
通过
$group_value = $value['group'] == "7777" || $value['group'] == "6000" ? $value['group'] : "Others";
$result[$i][$group_value][] = array($value['code'], $value['group']);
现在var_dump($result);
的输出是:
array (size=1)
0 =>
array (size=5)
'name' => string 'John Doe' (length=8)
'age' => string '36' (length=2)
'Others' =>
array (size=4)
0 =>
array (size=2)
0 => string '437' (length=3)
1 => string '1000' (length=4)
1 =>
array (size=2)
0 => string '437' (length=3)
1 => string '4000' (length=4)
2 =>
array (size=2)
0 => string '437' (length=3)
1 => string '4000' (length=4)
3 =>
array (size=2)
0 => string '437' (length=3)
1 => string '5000' (length=4)
7777 =>
array (size=2)
0 =>
array (size=2)
0 => string '437' (length=3)
1 => string '7777' (length=4)
1 =>
array (size=2)
0 => string '437' (length=3)
1 => string '7777' (length=4)
6000 =>
array (size=2)
0 =>
array (size=2)
0 => string '437' (length=3)
1 => string '6000' (length=4)
1 =>
array (size=2)
0 => string '437' (length=3)
1 => string '6000' (length=4)
是您想要的吗?
答案 2 :(得分:0)
如果我自己说的话,这是一种严重依赖array_intersect的方法。
这是为了确保循环数保持尽可能低。
我仅循环唯一的名称,以及该名称内的唯一组。
$names = array_column($array, "name");
$groups = array_column($array, "group");
foreach(array_unique($names) as $name){
$intersects = array_intersect_key($array, array_intersect($names, [$name]));
$new[$name] = ["name" => $name, "age" => end($intersects)["age"]]; // Create the start of the array
foreach(array_unique($groups) as $group){ // loop only unique groups
$intersects = array_intersect_key($array, array_intersect($groups, [$group])); // find matching arrays with this group
foreach($intersects as $int){
$temp = array_diff($int, ["name" => $new[$name]["name"], "age" => $new[$name]["age"]]); // remove the name and age from the matching array and place them in 6000/7777 or others
if($temp["group"] == "6000" || $temp["group"] == "7777"){
$new[$name][$group][] = $temp;
}else{
$new[$name]["others"][] = $temp;
}
}
}
}
var_dump($new);
输出:
array(1) {
["John Doe"]=>
array(5) {
["name"]=>
string(8) "John Doe"
["age"]=>
string(2) "36"
["others"]=>
array(4) {
[0]=>
array(2) {
["code"]=>
string(3) "437"
["group"]=>
string(4) "1000"
}
[1]=>
array(2) {
["code"]=>
string(3) "437"
["group"]=>
string(4) "4000"
}
[2]=>
array(2) {
["code"]=>
string(3) "437"
["group"]=>
string(4) "4000"
}
[3]=>
array(2) {
["code"]=>
string(3) "437"
["group"]=>
string(4) "5000"
}
}
[7777]=>
array(2) {
[0]=>
array(2) {
["code"]=>
string(3) "437"
["group"]=>
string(4) "7777"
}
[1]=>
array(2) {
["code"]=>
string(3) "437"
["group"]=>
string(4) "7777"
}
}
[6000]=>
array(2) {
[0]=>
array(2) {
["code"]=>
string(3) "437"
["group"]=>
string(4) "6000"
}
[1]=>
array(2) {
["code"]=>
string(3) "437"
["group"]=>
string(4) "6000"
}
}
}
}
在其他答案的注释中,编辑将1000更改为6000。