[Php] Elementi comuni di due array

PHP:
<?php
/**
 * non deve essere restituita due volte se in uno dei due array è presente una volta
 * ma solo se in entrambi è presente due volte
 * Es. Presi due array (a, b, b, c) e (a, a, b, b,), il risultato voglio che sia (a, b, b)

 * ma forse il problema andrebbe formulato dicendo,

 * un elemento deve essere presente in tutte e due le array,
 * voglio sapere il minimo delle volte che vi compare
 * comunque faccia il confronto
**/

$a2 = array("a", "a", "b", "b");
$a1 = array("a", "b", "b", "c");

$c1 = array_count_values($a1);
$c2 = array_count_values($a2);

var_dump($c1); echo "<br />"; var_dump($c2); echo "<br />";

foreach ($c1 as $key => $val) {
    if (!empty($c2[$key]))
        echo " Key : ".$key." Value : ".min($val, $c2[$key])."<br />";
}

/**
 * RISULTATO 1

array(2) { ["a"]=> int(2) ["b"]=> int(2) }
array(3) { ["a"]=> int(1) ["b"]=> int(2) ["c"]=> int(1) }
 Key : a Value : 1
 Key : b Value : 2

 * RISULTATO 2 (scambiando le array di partenza)

array(3) { ["a"]=> int(1) ["b"]=> int(2) ["c"]=> int(1) }
array(2) { ["a"]=> int(2) ["b"]=> int(2) }
 Key : a Value : 1
 Key : b Value : 2

**/
?>

altrimenti qual è la regola da applicare ?
 
Codice:
<?php
/**
* non deve essere restituita due volte se in uno dei due array è presente una volta
* ma solo se in entrambi è presente due volte
* Es. Presi due array (a, b, b, c) e (a, a, b, b,), il risultato voglio che sia (a, b, b)
**/
$a1 = array("a", "a", "b", "b");
$a2 = array("a", "b", "b", "c");

$u1 = array_unique($a1);

$risultato = array_intersect($a2, $u1);

var_dump($risultato);

/**
* RISULTATO
* array(3) { [0]=> string(1) "a" [1]=> string(1) "b" [2]=> string(1) "b" }
**/
?>

Grazie del codice Marino51 ma il mio codice dovrà accettare due array qualunque e processarli nella stessa maniera. Quello che hai fornito tu vale solo per quel caso particolare.

Con mio grande piacere credo di aver quasi trovato la soluzione

Codice:
<?php
$a = array("a", "a", "b", "g", "r", "b");
$b = array("b", "b", "r", "g", "g", "a");

function verifica($array) {
  if (count(array_unique($array)) < count($array)) {
    $array_double = array_diff_assoc($array, array_unique($array)); //seleziono il valore doppio dell'array
  } else {
    break;
  }

  return $array_double;
}


$a_doubles = verifica($a);  //questo array contiene un solo elemento di ciascuna delle coppie di lettere uguali presenti nel primo array
$b_doubles = verifica($b);// idem per il secondo array

/*
print_r($a_doubles);
echo "<br>";
print_r($b_doubles);
echo "<br><br>";
*/

function trova_doppi($new, $new_2) {
  $d = array(); //array che conterrà le eventuali lettere che sono doppie in entrambi gli array

  foreach ($new as $val) {
    if (in_array($val, $new_2)) {
      $d[] = $val;
    }
  }

  return $d;
}

$d = trova_doppi($a_doubles, $b_doubles);

/*
print_r($d);
echo "<br><br>";
*/
  $c = array_unique(array_diff($a, array_diff($a, $b))); //processo i due array senza contare eventuali valori doppi in comune

if (!empty($d)) {
  $c = array_merge($c, $d);  //aggiungo eventuali valori doppi
}

print_r($c);
?>

Ho fatto varie prove con valori doppi e funziona a meraviglia. Peccato solo che in casi in cui ho due array simili: (a,a,a,b) e (a,a,b,b) mi dà (a,a,a)
 
Ultima modifica:
Grazie del codice Marino51 ma il mio codice dovrà accettare due array qualunque e processarli nella stessa maniera. Quello che hai fornito tu vale solo per quel caso particolare.
l'ultimo esempio è valido comunque

però sono molto meglio quei codici lunghi lunghi, meno soggetti ad errori ....
 
Grazie marino51, finalmente ho finito e testato il mio codice. Ora funziona alla perfezione in ogni situazione! Ringrazio anche borgo italia per l'aiuto datomi.

Codice:
<?php
$a = array("b", "h", "r", "r", "h", "g");
$b = array("b", "g", "r", "h", "c", "a");


//controllo se i due array contengono valori ripetuti
if (count(array_unique($a)) < count($a) && count(array_unique($b)) < count($b)) {
    $a_new = array_count_values($a);
    $b_new = array_count_values($b);
  } else {
    $c = array_intersect(array_unique($a), array_unique($b));
    print_r($c);
  }


/*
print_r($a_new);
echo "<br>";
print_r($b_new);
echo "<br><br>";
*/
if (!empty($a_new) && !empty($b_new)) {
  $d = array();

  foreach ($a_new as $key_a => $value_a) {
    foreach ($b_new as $key_b => $value_b) {
      if ($key_a == $key_b && $value_a < $value_b) {
        $array = array_fill(1, $value_a, $key_a);
        $array = array_flip($array);
        $d = array_merge($d, $array);
      } elseif ($key_a == $key_b && $value_a > $value_b) {
        $array = array_fill(1, $value_b, $key_b);
        $array = array_flip($array);
        $d = array_merge($d, $array);
      } elseif ($key_a == $key_b && $value_a == $value_b) {
        $array = array_fill(1, $value_b, $key_b);
        $array = array_flip($array);
        $d = array_merge($d, $array);
      } else {
        continue;
      }
    }
  }
}

/*
$d sarà un'array che avrà come chiavi i valori in comune fra i due array e
per valori il numero minimo di volte in cui compaiono in uno dei due
*/

/*
print_r($d);
echo "<br>";
$array_final = array();
$x = 1;
*/


if (!empty($d)) {
  foreach ($d as $valore => $numero_volte) {
    $x = 1;
    while ($x <= $numero_volte) {
      $array_final[] = $valore;
      $x++;
    }
  }


  print_r($array_final);
}


?>

Se credete poi che debba essere aggiustato od ottimizzato ditemi pure.
 
PHP:
$a = array("b", "h", "r", "r", "r", "h", "g");
$b = array("b", "g", "r", "h", "c", "a", "r");

$a_new = array_count_values($a);
$b_new = array_count_values($b);

$c = array_intersect(array_unique($a), array_unique($b));

$f = array();
$e = array();
foreach ($c as $key) {
    $e[$key] = min($a_new[$key], $b_new[$key]);
    for ($i = 0; $i<$e[$key]; $i++) {
        $f[]=$key;
    }
}
prova così,
array "f" contiene il risultato finale
array "e" le occorrenze "minime", che se non necessarie, anziché l'array si può usare una variabile semplice
risultato

Codice:
array a : Array ( [0] => b [1] => h [2] => r [3] => r [4] => r [5] => h [6] => g )
array b : Array ( [0] => b [1] => g [2] => r [3] => h [4] => c [5] => a [6] => r )

ottimizzato
array finale : Array ( [0] => b [1] => h [2] => r [3] => r [4] => g )

non ottimizzato
array finale : Array ( [0] => b [1] => h [2] => r [3] => r [4] => g )
 
Ultima modifica:

Discussioni simili