Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Merge and diff arrays of arrays to find common values

Tags:

php

I am trying to loop through several database table structures and determine the common structure (ie what columns are identical). The final structure should only show common columns, so if any table has a unique column, it should not be in the final array.

This is an example of what three table structures may look like.

$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];

Using array_merge, array_diff, array_intersect, or a loop, is it possible to determine which of these columns are common to all tables?

The end value should be [["name"=>"col1", "type"=>"varchar"]]

like image 595
billy_bones_3 Avatar asked Jul 03 '18 14:07

billy_bones_3


People also ask

How do I combine multiple arrays into one?

The concat() method concatenates (joins) two or more arrays. The concat() method returns a new array, containing the joined arrays. The concat() method does not change the existing arrays.

How can I find not matching values in two arrays?

JavaScript finding non-matching values in two arrays The code will look like this. const array1 = [1, 2, 3, 4, 5, 6]; const array2 = [1, 2, 3, 4, 5, 6, 7, 8, 9]; const output = array2. filter(function (obj) { return array1. indexOf(obj) === -1; }); console.

How to merge two arrays in C++?

In order to merge two arrays, we find its length and stored in fal and sal variable respectively. After that, we create a new integer array result which stores the sum of length of both arrays. Now, copy each elements of both arrays to the result array by using arraycopy () function.

How to get common elements of two arrays in C++?

Following is the algorithm used to get the common elements. Algorithm: Firstly, sort both the arrays. Then, Keep a pointer for each of the two arrays. If both elements that are being pointed are equal, then it is a common element. Otherwise, increment the pointer of the array with a lower value of the current element.

What do you mean by'get common elements from two arrays'?

These elements can be of the same or different data types. Few examples of arrays are, By ‘get common elements from two arrays’, here we mean the mathematical intersection of two arrays. Those elements which are present in both the arrays are referred to as common elements here.

How to merge two sorted arrays in a sorted manner?

Given two sorted arrays, the task is to merge them in a sorted manner. Recommended: Please solve it on “ PRACTICE ” first, before moving on to the solution. Create an array arr3 [] of size n1 + n2. Traverse arr2 [] and one by one insert elements (like insertion sort) of arr3 [] to arr1 []. This step take O (n1 * n2) time.


Video Answer


2 Answers

You could use array_uintersect, which does the intersection with your own function. But you should keep in mind, that the compare function does not simply returns true or false - instead you have to return -1, 0 or 1.

In PHP7 you could use the spaceship operator <=> for the comparison.

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

If you want to put all arrays inside the intersection, you could do this:

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

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

In older versions, you should instead use strcasecmp.

like image 161
Philipp Avatar answered Sep 25 '22 20:09

Philipp


You can use a custom compare method with 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))) ;
}

Will output:

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

)

Note:

@Abracadaver made a good point this method will only work correctly when you have the array conventions in the same order.

Than you can for example use this:

function compareDeepValue($val1, $val2)
{
    return ($val1['name'] === $val2['name'] && $val1['type'] === $val2['type']) ? 0 : -1;
}
like image 25
Timmetje Avatar answered Sep 23 '22 20:09

Timmetje