I have the following multidimensional array:
$ancestors = array(
[1] =>array("Andrew","Adele"),
[2] =>array("Bertha","Bill","Billy","Blake"),
[3] =>array("Cathy","Case","Cory","Creek","Andrew","Ceaser","Cece","Childer"));
I am trying to search the rows and return duplicate values along with the array key of the lowest number the duplicate appears and return values to an associative array:
$common = array("Andrew"=>"1");
// merge all array in one
$new = array();
foreach($ancestors as $i)
$new = array_merge($new, $i);
// make array value => count and sort in in descendant order
$ar = array_count_values($new);
arsort($ar);
// save result array while count > 1
$result = array();
foreach($ar as $k => $v) {
if ($v < 2) break;
$result[$k] = array_search($k, $new) + 1;
}
print_r($result);
First combine all the names into one array, with names as keys and arrays of generation indexes as values:
foreach ($ancestors as $generation_key => $generation) {
foreach ($generation as $name) {
$combined[$name][] = $generation_key;
}
}
Then limit the combined results to values having more than one instance of the name:
$duplicates = array_filter($combined, function($x) { return count($x) > 1; });
Then convert the arrays to single values using min
:
foreach ($duplicates as &$value) {
$value = min($value);
}
unset($value);
We have to compare each row with following rows, so row 1 with 2 and 3, row 2 with 3, row 3 with nothing (it is already compared). To do this, we use a base-1 for
to loop through all $ancestors
elements except last, then we compare each name with greater ancestors:
$result = array();
/* Loop count($ancestors) -1: */
for( $i = 1; $i<count( $ancestors ); $i++ )
{
/* Loop for each name: */
foreach( current( $ancestors ) as $val )
{
/* If name is already in result, skip: */
if( isset( $result[$val] ) ) continue;
/* Loop for each following ancestors: */
foreach( array_slice( $ancestors, $i, Null, True ) as $key => $row )
{
if( in_array( $val, $row ) ) $result[ $val ] = key( $ancestors );
}
}
next( $ancestors );
}
For this $ancestors
:
$ancestors = array(
1 =>array( "Andrew","Adele" ),
2 =>array( "Bertha","Bill","Billy","Blake","Adele" ),
3 =>array( "Cathy","Case","Cory","Creek","Andrew","Ceaser","Bill","Cece","Childer" ),
4 =>array( "Cathy" )
);
the result is:
Array
(
[Andrew] => 1
[Adele] => 1
[Bill] => 2
[Cathy] => 3
)