合并和比较数组的数组以查找公共值

时间:2018-07-03 14:32:44

标签: php

我试图遍历几种数据库表结构并确定通用结构(即哪些列相同)。最终结构应仅显示公共列,因此,如果任何表具有唯一列,则其不应位于最终数组中。

这是三个表结构的示例。

$arr1 = [
    ["name"=>"col1", "type"=>"varchar"],
    ["name"=>"col2", "type"=>"int"]    
];
$arr2 = [
    ["name"=>"col1", "type"=>"varchar"],
    ["name"=>"col2", "type"=>"int"]    ,
    ["name"=>"col3", "type"=>"date"]    
];
$arr3 = [
    ["name"=>"col1", "type"=>"varchar"],
    ["name"=>"col3", "type"=>"int"]    
];

$arrays = [$arr1, $arr2, $arr3];

使用array_mergearray_diffarray_intersect或循环,是否可以确定所有表中共有哪些列?

最终值应为 [["name"=>"col1", "type"=>"varchar"]]

5 个答案:

答案 0 :(得分:5)

您可以使用array_uintersect,它与您自己的函数相交。但是请记住,比较函数不能简单地返回true或false-而是必须返回-101

在PHP7中,您可以使用飞船运算符<=>进行比较。

$intersection = array_uintersect($arr1, $arr2, $arr3, function($a, $b) {
    $ret = $a['name'] <=> $b['name'];
    return $ret ? $ret : $a['type'] <=> $b['type'];
});
print_r($intersection);

如果要将所有数组放在交点内,则可以执行以下操作:

$arrays = [$arr1, $arr2, $arr3];
$arrays[] = function($a, $b) {
    $ret = $a['name'] <=> $b['name'];
    return $ret ? $ret : $a['type'] <=> $b['type'];
};

$intersection = array_uintersect(...$arrays);

在旧版本中,您应该使用strcasecmp

答案 1 :(得分:3)

您可以对array_uintersect()使用自定义比较方法:

$arr1 = [
    ["name" => "col1", "type" => "varchar"],
    ["name" => "col2", "type" => "int"]
];
$arr2 = [
    ["name" => "col1", "type" => "varchar"],
    ["name" => "col2", "type" => "int"],
    ["name" => "col3", "type" => "date"]
];
$arr3 = [
    ["name" => "col1", "type" => "varchar"],
    ["name" => "col3", "type" => "int"]
];

$common_columns = array_uintersect($arr1, $arr2, $arr3, 'compareDeepValue');

print_r($common_columns);

function compareDeepValue($val1, $val2)
{
    return (strcasecmp(serialize($val1), serialize($val2))) ;
}

将输出:

Array
(
    [0] => Array
        (
            [name] => col1
            [type] => varchar
        )

)

注意:

@Abracadaver提出了一个很好的建议,该方法仅在您具有相同顺序的数组约定时才能正确使用。

例如,您可以使用以下功能:

function compareDeepValue($val1, $val2)
{
    return ($val1['name'] === $val2['name'] && $val1['type'] === $val2['type']) ? 0 : -1;
}

答案 2 :(得分:1)

您可以使用name键提取数组和索引,并使用以下键计算交集:

$result = array_intersect_key(array_column($arr1, null, 'name'),
                              array_column($arr2, null, 'name'),
                              array_column($arr3, null, 'name'));

收益:

Array
(
    [col1] => Array
        (
            [name] => col1
            [type] => varchar
        )
)

如果需要,请使用array_values返回数字索引。

答案 3 :(得分:0)

也许吗?

$arrays = [$arr1, $arr2, $arr3];
$arrays_extended = [];

foreach($arrays as $row => $innerArray){
  foreach($innerArray as $innerRow => $value){
    array_push($arrays_extended, $value);
  }
}

var_dump(array_unique($arrays_extended));
  

输出[["name"=>"col1", "type"=>"varchar"]]

答案 4 :(得分:0)

方法:

1。将元素转换为字符串,如下所示:

 array(2) {
      [0] =>
      string(32) "{"name":"col1","type":"varchar"}"
      [1] =>
      string(28) "{"name":"col2","type":"int"}"
    }
    array(3) {
      [0] =>
      string(32) "{"name":"col1","type":"varchar"}"
      [1] =>
      string(28) "{"name":"col2","type":"int"}"
      [2] =>
      string(29) "{"name":"col3","type":"date"}"
    }
    array(2) {
      [0] =>
      string(32) "{"name":"col1","type":"varchar"}"
      [1] =>
      string(28) "{"name":"col3","type":"int"}"
    }

2。使用数组相交找到共同的元素

3。转换回数组。

$arr1 = [
    ["name"=>"col1", "type"=>"varchar"],
    ["name"=>"col2", "type"=>"int"]    
];
$arr2 = [
    ["name"=>"col1", "type"=>"varchar"],
    ["name"=>"col2", "type"=>"int"]    ,
    ["name"=>"col3", "type"=>"date"]    
];
$arr3 = [
    ["name"=>"col1", "type"=>"varchar"],
    ["name"=>"col3", "type"=>"int"]    
];

list($darr1, $darr2, $darr3) = convertArrToStr($arr1, $arr2, $arr3);
/* output:
array(2) {
  [0] =>
  string(32) "{"name":"col1","type":"varchar"}"
  [1] =>
  string(28) "{"name":"col2","type":"int"}"
}
array(3) {
  [0] =>
  string(32) "{"name":"col1","type":"varchar"}"
  [1] =>
  string(28) "{"name":"col2","type":"int"}"
  [2] =>
  string(29) "{"name":"col3","type":"date"}"
}
array(2) {
  [0] =>
  string(32) "{"name":"col1","type":"varchar"}"
  [1] =>
  string(28) "{"name":"col3","type":"int"}"
}
 */
var_dump(duplicates($darr1, $darr2, $darr3));
/* output:
array(1) {
  [0] =>
  array(2) {
    'name' =>
    string(4) "col1"
    'type' =>
    string(7) "varchar"
  }
}
*/    

function convertArrToStr() {
    $args = func_get_args();
    foreach($args as &$arg){
          foreach($arg as $k => $arr) {
                      $arg[$k] = json_encode($arr, true);
          }
    }
    return $args;
}

function duplicates($darr1, $darr2, $darr3) {
    $intersects = array_intersect($darr1, $darr2, $darr3);
    $r = [];
    foreach($intersects as $v) {
          $r[] = json_decode($v, true);    
    }
    return $r;
}

希望这可以帮助您编写更优雅的解决方案。