[Php] Elementi comuni di due array

JeanWolf

Nuovo Utente
31 Dic 2016
20
0
1
24
Dati due array (di lunghezza unguale e già definita) voglio trovarne gli elementi in comune. Ho pensato quindi di struttare il codice così:

PHP:
<?php
$ar_1 = array("b", "d", "t", "f", "f", "w");
$ar_2 = array("w", "w", "b", "f", "t", "n");


$val_1 = 0;
$val_2 = 0;

while ($val_1 < 7) {
if ($ar_1[$val_1] == $ar_2[$val_2]) {
    echo $ar_2[$val_2];
    $val_1++;
    $val_2 = 0;
  } else {
    if ($val_2 >= 7) {
      $val_2 = 0;
      $val_1++;
    } else {
      $val_2++;
    }
  }
}
?>
Innanzitutto vorrei chiedere cosa si potrebbe migliorare di questo codice (sono un principiante al mio primo script) e in secondo luogo chiedere una soluzione per gestire le doppie lettere (in questo caso ad esempio nell'output viene ripetuta due volte la "f" nonostante ce ne sia solo una in comune tra i due array).
Grazie in anticipo
 
Ultima modifica di un moderatore:

JeanWolf

Nuovo Utente
31 Dic 2016
20
0
1
24
Ho letto al pagina in questione, ma un problema rimane.
Se ad esempio ho questi due array:
Codice:
$ar_1 = array("b", "d", "t", "f", "f", "w");
$ar_2 = array("w", "w", "b", "f", "t", "n");
ho ancora il problema di come far determinare le lettere in comune allo script qualora esse si presentino in duplice valore nello stesso array. Finchè l'array con lettere doppie era uno era semplice farlo, bastava metterlo per secondo nella funzione intersect, ma il problema arriva se, come nell'esempio, sono entrambi gli array ad avere valori duplici e, se sono presenti in entrambi gli array in duplice valore, bisogna mantenerli altrimenti lasciarne solo uno.
Spero di essermi spiegato bene
 

JeanWolf

Nuovo Utente
31 Dic 2016
20
0
1
24
Ho provato a creare una funzione che determina quali siano i valori doppi di un array (così poi da confrontarli con quelli doppie dell'altro array)

Codice:
<?php
$ar_1 = array("b", "d", "t", "f", "f", "w");
$ar_2 = array("w", "w", "b", "f", "t", "n");


function doppi($array) {

    $cont = 0;
    $i = 0;

  while ($cont <= 7) {


    if ($array[$cont] == $array[$i] && $cont != $i) {
      $double = $array[$cont];
      $i = 0;
      $cont++;}


    if ($i >= 7){
      $i = 0;
      $cont++;}

    $i++;
  }

return $double;
}


echo doppi($ar_1);
?>
Ma non funziona. Sapreste dirmi cosa ho sbagliato?
 

JeanWolf

Nuovo Utente
31 Dic 2016
20
0
1
24
Ho finalmente risolto tutto con questo script

PHP:
<?php
$ar_1 = array("b", "d", "t", "f", "f", "w");
$ar_2 = array("w", "w", "b", "f", "t", "n");

function doppi($array) {

  $cont = 0;
  $i = 0;

  while ($cont <= 7) {

    if ($array[$cont] == $array[$i] && $cont != $i) {
      $double = $array[$cont];
      $i = 0;
      $cont++;
    break;}

    if ($i >= 7){
      $i = 0;
      $cont++;}

    $i++;
  }

  return $double;

}


if (doppi($ar_1) == doppi($ar_2)) {
  $ar = array_intersect($ar_1, $ar_2);
} else {
  $ar = array_intersect(array_unique($ar_1), array_unique($ar_2));
}

print_r($ar);
?>
Chiedo se ho strutturato bene il codice e cosa potrei migliorare e soprattutto perchè la funzione funziona se al primo if c'è un break (nell'altro codice infatti non avevo messo un break e il valore $double veniva stampato una decina di volte)
 
Ultima modifica di un moderatore:

borgo italia

Super Moderatore
Membro dello Staff
SUPER MOD
MOD
4 Feb 2008
16.042
146
63
PR
www.borgo-italia.it
ciao
col tuo script ottieni
Array ( [0] => b [2] => t [3] => f [5] => w )
ora se è quello che vuoi ottenere (uso function per fare come hai fatto tu)
PHP:
<?php
function doppi($a_1, $a_2){
    $a_1 =array_unique($a_1);
    $a_2 =array_unique($a_2);
    $ar = array_intersect($a_1, $a_2);
    $ar = array_values($ar);//riordina gli indici da 0 in poi
    return $ar;
}
/*******/
$ar_1 = array("b", "d", "t", "f", "f", "w");
$ar_2 = array("w", "w", "b", "f", "t", "n");
print_r(doppi($ar_1,$ar_2));
?>
output
Array( [0] => b [1] => t [2] => f [3] => w )
cioè da quello che capisco quello che vuoi fare

con il pregio che funziona anche se i due array hanno lunghezza diversa e con meno righe di codice
 

JeanWolf

Nuovo Utente
31 Dic 2016
20
0
1
24
Così però se entrambi gli array presentano gli stessi valori doppi (es. Entrambi hanno la lettera w ripetuta) uno di essi viene automaticamente cancellato dalla funzione array_unique mentre il mio obbiettivo è di mostrare le lettere in comune, doppie comprese (purché siano presenti in entrambi gli array)
 

borgo italia

Super Moderatore
Membro dello Staff
SUPER MOD
MOD
4 Feb 2008
16.042
146
63
PR
www.borgo-italia.it
ciao
guarda che quello che hai postato in cui hai detto risolto restituisce la stessa cosa, es la 'f' presente in arr_1 2 volte e una in arr_2 viene col tuo script mostrato una volta sola
 

JeanWolf

Nuovo Utente
31 Dic 2016
20
0
1
24
Perché infatti 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)
 
Ultima modifica:

borgo italia

Super Moderatore
Membro dello Staff
SUPER MOD
MOD
4 Feb 2008
16.042
146
63
PR
www.borgo-italia.it
ciao
ribadisco, con il tuo ultimo script, se hai come nell'ultimo post
$ar_1 = array('a',' b', 'b', 'c');//(a, b, b, c)
$ar_2 = array('a',' a', 'b', 'b');//(a, a, b, b)

NON ottieni un array
Array ( [0] => a [1] => b [2] => b)//(a, b, b)
come dici tu
ma
Array ( [0] => a [2] => b )//(a, b)

p.s.
fatto copy/paste del tuo e provato
 

JeanWolf

Nuovo Utente
31 Dic 2016
20
0
1
24
Allora mi sa che dovrei riscrivere dall'inizio lo script, qualche idea a riguardo su come crearlo?
 

JeanWolf

Nuovo Utente
31 Dic 2016
20
0
1
24
Ovviamente stai tranquillo, anzi ti ringrazio per il tempo già dedicatomi :)
 

borgo italia

Super Moderatore
Membro dello Staff
SUPER MOD
MOD
4 Feb 2008
16.042
146
63
PR
www.borgo-italia.it
ciao
prova questo
PHP:
<?php
function doppi($a_1, $a_2){
    $quanti=array();
    foreach($a_1 as $ch1 => $val1){
        foreach($a_2 as $ch2 => $va2){
            if($val1==$va2){
                $quanti[]=$val1;
            }
        }
        
    }
    return $quanti;
}
echo "<pre>";//messo per visualizzare meglio il print_r
//$ar_1 = array("b", "d", "t", "f", "f", "w", "y","y");
//$ar_2 = array("y","y","w", "w", "b", "f", "t", "n");
$ar_1 = array('a',' b', 'b', 'c');
$ar_2 = array('a',' a', 'b', 'b');
$risultato=doppi($ar_1,$ar_2);
print_r($risultato);
/*output
Array
(
    [0] => a
    [1] => b
    [2] => b
)
*/
echo "</pre>";
?>
però fai delle prove con varie combinazioni di array
 

JeanWolf

Nuovo Utente
31 Dic 2016
20
0
1
24
1° TEST

Ho aggiunto al primo array due valori uguali "c" e al secondo uno solo di essi, così :

Codice:
$ar_1 = array('a',' b', 'b', 'c', 'c');
$ar_2 = array('a',' a', 'b', 'b', 'c');
e come output mi dà:

Codice:
Array
(
    [0] => a
    [1] => b
    [2] => b
    [3] => c
    [4] => c
)
E non :

Codice:
Array
(
    [0] => a
    [1] => b
    [2] => b
    [3] => c
)
Dato che solo una "c" è in comune fra i due array.

2° TEST

Ho cambiato poi di nuovo una sola lettera degli array in modo da trasformali così:

Codice:
$ar_1 = array('a',' b', 'b', 'b', 'c');
$ar_2 = array('a',' a', 'b', 'c', 'c');
E il risultato che mi dà è:

Codice:
Array
(
    [0] => a
    [1] => b
    [2] => b
    [3] => c
    [4] => c
)

MIO (NUOVO) SCRIPT

Partendo da zero ho voluto prima creare un piccolo script (che poi ovviamente diventerà una funzione) che, prendendo in ingresso un solo array determini quante e quali lettere doppie e le riscriva tutte in un nuovo array. L'ho strutturato perciò così:

Codice:
<?php
$array = array("b", "b", "d", "g", "d", "a");
$k = 0;
$v = 0;

while ($k <= 7) {

  if ($k != $v && $array[$k] == $array[$v]) {
    $ar_1[] = $array[$k];
    $v++;
  } elseif ($v == 7){
    $k++;
    $v = 0;
  } else {
    $v++;
  }
}

print_r($ar_1); //Mi aspetto che stampi le lettere doppie dell'array ossia "b" e "d"
?>
Ma non funziona perchè infatti il codice genera questo errore:

Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 71 bytes) in /usr/local/ampps/www/cesare/0_1.php on line 9
Se invece aggiungo un "break" al primo "if", il codice funziona ma mi stampa solo la "b" (quando invece a me serve che stampi anche la "d"). Facendo altre prove sembra che il problema lo dia proprio la riga in questione

Codice:
  if ($k != $v && $array[$k] == $array[$v]) {
    $ar_1[] = $array[$k];
    $v++;
  }
Non capisco però cosa sbaglio nella logica dal momento che il contatore và comunque avanti.

P.S. Che disagio il mio primo script, spero non sia un chiaro indizio di quanto sia negato a programmare :p
 

JeanWolf

Nuovo Utente
31 Dic 2016
20
0
1
24
Forse mi sono espresso male io. Quando intendo una "c" in comune mi riferisco a questa situazione esempio:
(a,b,c) e (a,c,c) e faccio riferimento all'output che vorrei ottenere ossia (a,c) e non (a,c,c).
Lo stesso discorso che facevo prima per la "b".
 

marino51

Utente Attivo
28 Feb 2013
2.955
171
63
Lombardia
spesso io ho idee confuse ... ma in questo caso ancora di più ....
array_unique($array1)
array_unique($array2)
array_intersect($array1, $array2)
array_intersect($array2, $array1)
 

JeanWolf

Nuovo Utente
31 Dic 2016
20
0
1
24
Con array_unique vengono eliminati automaticamente i valori uguali negli array, ma io voglio che essi siano stampati se presenti anche nell'array di confronto
es. Array1 = (a,b,b,c)
Array2 = (b,b,c,d)
Output che vorrei (b,b,c)
 
Ultima modifica:

marino51

Utente Attivo
28 Feb 2013
2.955
171
63
Lombardia
Perché infatti 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)
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)
**/
$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" }
**/
?>
Capisco che il manuale non interloquisce attraverso WhatsApp, twitter, facebook ...
ma deve essere consultato con metodi tradizionali enormemente faticosi,
poi dovrebbe essere anche ben chiaro cosa si vuole,
cambiare il proprio desiderio alla vista del risultato ...
aumenta la confusione delle mie poche idee e già di per loro confuse
 
Ultima modifica: