【问题标题】:Combining Multidimensional Arrays组合多维数组
【发布时间】:2017-03-27 21:06:43
【问题描述】:

我有两个数组,我想根据三个值(group_id、user_id、unit_id)的匹配来组合。如果这些值出现在一个数组中而不出现在另一个数组中,我想插入一个字符串来指示不存在值。

数组 1:

Array
(
    [0] => Array
        (
            [group_id] => 1
            [user_id] => 7
            [unit_id] => 21382
            [amount] => 500
            [type] => A
        )

    [1] => Array
        (
            [group_id] => 1
            [user_id] => 7
            [unit_id] => 24255
            [amount] => 300
            [type] => A
        )

    [2] => Array
        (
            [group_id] => 1
            [user_id] => 4
            [unit_id] => 21382
            [amount] => 50
            [type] => A
        )

    [3] => Array
        (
            [group_id] => 1
            [user_id] => 4
            [unit_id] => 24255
            [amount] => 67
            [type] => A
        )
)

数组 2:

Array
(
    [0] => Array
        (
            [group_id] => 1
            [user_id] => 7
            [unit_id] => 21382
            [amount] => 100
            [type] => B
        )

    [1] => Array
        (
            [group_id] => 1
            [user_id] => 7
            [unit_id] => 24255
            [amount] => 82
            [type] => B
        )
)

期望的结果:

Array
(
    [0] => Array
        (
            [group_id] => 1
            [user_id] => 7
            [unit_id] => 21382
            [A] => 500
            [B] => 100
        )

    [1] => Array
        (
            [group_id] => 1
            [user_id] => 7
            [unit_id] => 24255
            [A] => 300
            [B] => 82
        )
    [2] => Array
        (
            [group_id] => 1
            [user_id] => 4
            [unit_id] => 21382
            [A] => 50
            [B] => undefined
        )

    [3] => Array
        (
            [group_id] => 1
            [user_id] => 4
            [unit_id] => 24255
            [A] => 67
            [B] => undefined
        )
)

使用 foreach 循环我设法获得了部分结果,但这并不能说明值出现在一个数组中而不是另一个数组中的情况。

foreach ($array_1 as &$arr1) {
    foreach ($array_2 as $arr2) {
        if ($arr1['group_id'] == $arr2['group_id'] && $arr1['user_id'] == $arr2['user_id'] && $arr1['unit_id'] == $arr2['unit_id']) {
            $newArr[] = array('group_id'=>$arr1['group_id'], 'user_id'=>$arr1['user_id'], 'unit_id'=>$arr1['unit_id'], 'group_id'=>$arr1['group_id'], 'A'=>$arr1['amount'], 'B'=>$arr2['amount']);
            break;
        }
    }
}

【问题讨论】:

    标签: php arrays multidimensional-array associative-array


    【解决方案1】:

    我的尝试,您可以将其他数组添加到 array_merge 命令。或者轻松添加类型,也可以在源数组中混合类型。

        $arr1 = array(
            array(
                'group_id' => 1,
                'user_id' => 7,
                'unit_id' => 21382,
                'amount' => 500,
                'type' => 'A',
            ),
            array(
                'group_id' => 1,
                'user_id' => 7,
                'unit_id' => 24255,
                'amount' => 300,
                'type' => 'A',
            ),
            array(
                'group_id' => 1,
                'user_id' => 4,
                'unit_id' => 21382,
                'amount' => 50,
                'type' => 'A',
            ),
            array(
                'group_id' => 1,
                'user_id' => 4,
                'unit_id' => 24255,
                'amount' => 67,
                'type' => 'A',
            ),
        );
    
        $arr2 = array(
            array(
                'group_id' => 1,
                'user_id' => 7,
                'unit_id' => 21382,
                'amount' => 100,
                'type' => 'B',
            ),
            array(
                'group_id' => 1,
                'user_id' => 7,
                'unit_id' => 24255,
                'amount' => 82,
                'type' => 'B',
            ),
        );
    
        $arrMerged = array_merge($arr1, $arr2);
        $desired = array();
    
        foreach ($arrMerged as $key => $val) {
            $retKey = false;
            foreach($desired as $desKey => $desVal) {
                if($desVal['group_id'] == $val['group_id']
                && $desVal['user_id'] == $val['user_id']
                && $desVal['unit_id'] == $val['unit_id']
                ) {
                    $retKey = $desKey;
                    break;
                }
            }
            if($retKey === false) {
                $desired[] = array(
                    'group_id' => $val['group_id'],
                    'user_id' => $val['user_id'],
                    'unit_id' => $val['unit_id'],
                    'A' => ($val['type'] == 'A' ? $val['amount'] : 'undefined'),
                    'B' => ($val['type'] == 'B' ? $val['amount'] : 'undefined'),
                );
            } else {
                $desired[$retKey][$val['type']] = $val['amount'];
            }
        }
    
        var_dump($desired);
    

    【讨论】:

      【解决方案2】:

      嵌套循环导致 O(n2) 复杂度非常昂贵。

      如果您通过合并键(下面的 sn-p 中的$uKey)对数组进行索引,则可以对线性 O(n) 复杂度进行相同操作。

      /**
       * build index
       *
       * @var array $index cumulative index
       * @var array $array array to add to index
       * @var array $uKey array of unique key names
       * @var array $template array of 'undefined' elements
       * @var string $char key to hold 'amount' value from $array
       */
      function index(&$index, $array, $uKey, $template, $char) {
          foreach($array as $a) {
              $key = json_encode(array_intersect_key($a, $uKey));
              $val = isset($index[$key]) ? $index[$key] : [];
              $index[$key] = array_merge($template, $val, [$char => $a['amount']]);
          }      
      }
      
      // init empty index
      $index = [];
      
      // define vector
      $uKey = array_flip(['group_id', 'user_id', 'unit_id']);
      
      // define template
      $template = ['A' => 'undefined', 'B' => 'undefined'];
      
      // add arrays to index
      index($index, $array1, $uKey, $template, 'A');
      index($index, $array2, $uKey, $template, 'B');
      
      // format index to reqquested output
      $result = [];
      foreach($index as $key=>$val) {
          $result[] = array_merge(json_decode($key, true), $val);
      }
      print_r($result)
      

      【讨论】:

        【解决方案3】:

        假设 array1 将始终具有类型 A,而 array2 将具有类型 B 值/数量,下面的代码将给出所需的输出。

        $array1 = array(
        '0' => array('group_id' => 1,'user_id' => 7,'unit_id' => 21382, 'amount' => 500,'type' => 'A'),
        '1' => array ('group_id' => 1, 'user_id' => 7,'unit_id' => 24255,'amount' => 300,'type' => 'A'),
        '2' => array( 'group_id' => 1, 'user_id' => 4, 'unit_id' => 21382, 'amount' => 50,'type' => 'A' ),
        '3' => array('group_id' => 1,'user_id' => 4,'unit_id' => 24255, 'amount' => 67, 'type' => 'A')
        );
        
        $array2 = array(
            '0' => array('group_id' => 1,'user_id' => 7,'unit_id' => 21382,'amount' => 100,'type' => 'B', ),
            '1' => array('group_id' => 1,'user_id' => 7,'unit_id' => 24255,'amount' => 82,'type' => 'B',)
        );
        // define an array
        $new_array = array();
        // loop first array
        foreach($array1 as $key=>$value){
            // generate unique key
            $unique_key = $value['group_id'].'_'.$value['user_id'].'_'.$value['unit_id'];
            // loop the second array
            foreach($array2 as $k=>$v){
                // check the condition
                if ($value['group_id'] == $v['group_id'] && $value['user_id'] == $v['user_id'] && $value['unit_id'] == $v['unit_id']) {
                   // generate array
                   $new_array[$unique_key]=array('group_id'=>$value['group_id'],
                   'user_id'=>$value['user_id'],
                   'unit_id'=>$value['unit_id'],
                   $value['type']=>$value['amount'],
                   $v['type'] => $v['amount']
                   ) ; 
                }else{
                    $new_array[$unique_key]=array(
                        'group_id'=>$value['group_id'],
                   'user_id'=>$value['user_id'],
                   'unit_id'=>$value['unit_id'],
                   $value['type']=>$value['amount'],
                   $v['type'] => 'Undefined'
                   ) ;  
                }  
            }  
        }
        // returns indexed array with values 
        $final_array = array_values($new_array);
        print_r($final_array);
        

        输出:

        Array
        (
        [0] => Array
            (
                [group_id] => 1
                [user_id] => 7
                [unit_id] => 21382
                [A] => 500
                [B] => 100
            )
        
        [1] => Array
            (
                [group_id] => 1
                [user_id] => 7
                [unit_id] => 24255
                [A] => 300
                [B] => 82
            )
        
        [2] => Array
            (
                [group_id] => 1
                [user_id] => 4
                [unit_id] => 21382
                [A] => 50
                [B] => Undefined
            )
        
        [3] => Array
            (
                [group_id] => 1
                [user_id] => 4
                [unit_id] => 24255
                [A] => 67
                [B] => Undefined
            )
        
        )
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-04-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多