PHP多维数组:对重复值进行分组并创建“子数组”

时间:2017-02-01 16:21:06

标签: php arrays multidimensional-array

我有一个重复值的数组,如下所示:

Array
(
    [0] => Array
        (
            [id] => 112
            [name] => John
            [country] => Spain
            [age] => 24
            [company] => One
            [price] => 10
        )
    [1] => Array
        (
            [id] => 112
            [name] => John
            [country] => Spain
            [age] => 24
            [company] => Two
            [price] => 15
        )
    [2] => Array
        (
            [id] => 112
            [name] => John
            [country] => Spain
            [age] => 24
            [company] => Three
            [price] => 20
        )
    [3] => Array
        (
            [id] => 224
            [name] => Paul
            [country] => France
            [age] => 25
            [company] => One
            [price] => 25
        )
    [4] => Array
        (
            [id] => 224
            [name] => Paul
            [country] => France
            [age] => 25
            [company] => Two
            [price] => 40
        )
)

我需要将idnamecountryage分组,并使用companies创建“子数组”companyprice

Array
(
    [112] => Array
        (
            [id] => 112
            [name] => John
            [country] => Spain
            [age] => 24
            [companies] => array (
                                  array(
                                        [company] => One 
                                        [price] => 10
                                  )
                                  array(
                                        [company] => Two
                                        [price] => 15
                                  )
                                  array(
                                        [company] => Three
                                        [price] => 20
                                  )
                           )               
        )

    [224] => Array
        (
            [id] => 2
            [name] => Paul
            [country] => France
            [age] => 25
            [companies] => array (
                                  array(
                                        [company] => One 
                                        [price] => 25
                                  )
                                  array(
                                        [company] => Two
                                        [price] => 40
                                  )
                           )               
        )           
)

我尝试过这段代码没有取得好成绩:

$new_array = array();
foreach ($my_array as $item) {      
    $new_array[$item['id']][] = $item;
    $new_array[$item['id']]['companies'][] = $item;

}

然后我尝试了这个:

$new_array = array();
foreach ($my_array as $item) {      
    $new_array[$item['id']]['temp'] = $item;
    $new_array[$item['id']]['companies'][] = $item;         
}

工作正常,但我得到temp密钥,我不想要它。例如,使用此代码,我需要使用id

访问$new_array [$key]['temp']['id']个项目

我可以用另一个循环删除temp键:

$final_array = array();
foreach ($new_array $key=>$item) {      
    $final_array [$key] = $item['temp'];
    $final_array [$key]['temp'] = $item['companies'];
}

使用此代码,我可以使用$final_array[$key]['id']

正确访问ID

另一个选择是这段代码:

foreach($array as $v) {
    $result[$v['id']]['id']          = $v['id'];
    $result[$v['id']]['name']        = $v['name'];
    $result[$v['id']]['country']     = $v['country'];
    $result[$v['id']]['age']         = $v['age'];
    $result[$v['id']]['companies'][] = array('company' => $v['company'],
                                             'price'   => $v['price']);
}

但如果我们有更多的钥匙(电话,电子邮件......),那就不是很优雅了。

有什么想法吗?

3 个答案:

答案 0 :(得分:1)

最后提供的代码没有任何问题,但是这里有一些关于如何让它更容忍更多数组值的想法(如你所提到的,电话,电子邮件等)。

这使用方便的PHP array_diff_key函数从“核心”记录中删除不需要的数组元素。然后,应用array_diff_key将这些相同的数组元素放入“公司”记录中。

// set up the array of keys you don't want in the "original" record
$exclude = ['company' => FALSE, 'price' => FALSE];
// Your original loop
foreach($array as $v) {
    // not strictly necessary, but helps readability
    $id = $v['id'];
    // Assign the "core" record all the values you want, excluding those defined above
    // in this case, will remove "company" and "price"
    $record = array_diff_key( $v, $exclude );

    // only set this if not already set, otherwise wipes out previous companies
    if ( ! isset($result[$id] ) ) {
        $result[$id] = $record;
        $result[$id]['companies'] = [];
    }

    // strip off the OTHER values from the array you don't want stored with the company
    // this will automatically pick up the field NOT excluded above
    // in this case, will remove all BUT "company" and "price"
    $company = array_diff_key( $v, $record );
    $result[$id]['companies'][] = $company;
}

答案 1 :(得分:0)

罗马的一种方式......

$collector=array();
foreach($array as $set){
 //get a copy
 $ref = $set;
 //unset company data
 unset($ref['company'],$ref['price']);
 //make a refer
 $r=$ref['id'];
 //setup main data if not set before
 if(!isset($collector[$r])){ 
    $collector[$r]=$ref;
 } 
 //collect company data
 $collector[$r]['companies'][] = array('company'=>$set['company'],'price'=>$set['price']);
}
print_r($collector);

答案 2 :(得分:0)

与其他答案类似:

$info = array (
    array('id' => 112, 'name' => 'John', 'country' => 'Spain', 'age' => 24, 'company' => 'One', 'price' => 10),
    array('id' => 112, 'name' => 'John', 'country' => 'Spain', 'age' => 24, 'company' => 'Two', 'price' => 15),
    array('id' => 112, 'name' => 'John', 'country' => 'Spain', 'age' => 24, 'company' => 'Three', 'price' => 20),
    array('id' => 224, 'name' => 'Paul', 'country' => 'France', 'age' => 25, 'company' => 'One', 'price' => 25),
    array('id' => 224, 'name' => 'Paul', 'country' => 'France', 'age' => 25, 'company' => 'Two', 'price' => 40)
);

$grouped = array();
foreach ($info as $item) {
    if (!isset($grouped[$item['id']])) {
        $grouped[$item['id']] = $item;
    }
    $grouped[$item['id']]['companies'][] = array($item['company'],$item['price']);
    unset($grouped[$item['id']]['company']);
    unset($grouped[$item['id']]['price']);
}

print_r($grouped);