• User Attivo

    Elementi in comune tra due array

    Salve a tutti avrei un problemino sto studiando il php ma non riesco per ora a risolverlo.
    Da una query mysql ottengo il sottoinsieme "A" degli id di una tabella di numero variabile a seconda dei record che vengono inseriti dalla normale attivita' del sito:
    $varA
    poi un'altra query mi da l' insieme "B"che e' maggiore di "A" e che contiene TUTTI elementi di "A".(A non contiene elementi non contenuti in B)
    $varB
    Vorrei eliminare gli elementi in comune tra B ed A ed ottenere l'insieme "C" degli elementi non comuni.
    Credo sia una cosa a cui arrivero' a breve con lo studio , ma avrei bisogno adesso di un aiuto per sistemare un programma di ufficio.

    Vi ringrazio.


  • User

    Ciao,

    dai un'occhiata alla funzione array_diff ( php.net/manual/en/function.array-diff.php ) 🙂


  • User

    Vedi se fa al caso tuo la funzione array_diff(): sottrae un array ad un altro.

    <?php
    $array1 = array("a" => "green", "red", "blue");
    $array2 = array("b" => "green", "red");
    $result = array_diff($array1, $array2);
    echo $result;
    ?>

    Avrai "blue".


  • User Attivo

    Ok allora la funzione e' chiara pero' i due array sono due variabili $idclienti e $idfornitori, tirate fuori da due query distinte
    la prima mi stampa 1 2 3 4 5 senza virgole o altro.
    la seconda mi stampa 1 2 3 4 5 6 7 8 9 sempre cosi' come le vedete.
    ora io ho bisogno di fare una sottrazione generale tra le due variabili non sapendo quali e quanti sono gli elementi xche' a loro volta variano di numero.
    Quindi il risultato dovra' essere 6 7 8 9.Come si scrive la funzione di cui sopra?


  • User Attivo

    La soluzione che ti è stata data da MatrixTeo e Celpunken fa esattamente quello che tu chiedi. Faccio fatica a capire se siamo noi ad aver male interpretato la tua domanda, o se sei tu a non aver capito la risposta.

    [php]
    <?php

    $idclienti = array(1, 2, 3, 4, 5);
    $idfornitori = array(1, 2, 3, 4, 5, 6, 7, 8, 9);
    $diff = array_diff($idclienti, $idfornitori);
    print_r($diff);

    ?>
    [/php]

    $diff sarà: array(6, 7, 8, 9)


  • User Attivo

    Grazie Fancesco, avete capito benissimo , il mio problema e' la sintassi, quei valori in parentesi sono valori di esempio ma sono costituiti dalle variabili $idclienti e $idfornitori che variano di continuo,
    la funzione non la posso scrivere con i valori tra parentesi ma con le variabili che li rappresentano. Cosa metto nelle parentesi?


  • User Attivo

    Variano di continuo perché sono in un while() che cicla su una query? Puoi postare per favore lo snippet di codice nel quale devi applicare questa funzione?


  • User

    Dovresti creare un array di appoggio da riempire con i tuoi elementi, poi si procede come scritto sopra, se ho capito bene.
    Scrivici una parte del codice 🙂


  • User Attivo

    $query1 = "SELECT * FROM tab1 WHERE localita='Napoli'";
    $result1 = mysql_query($query1, $link);
    if(mysql_num_rows($result1)){
    while($row = mysql_fetch_array($result1)){
    $idfornitori= stripslashes($row["id"]);
    echo"$idfornitori";

    uguale sara' un'altra query su una tab2 che mi da'
    $idclienti.
    ora alcuni fornitori sono anche clienti che nella tab 2 ripostano lo stesso id.

    quindi estrapolando i fornitori ad esempio 1 2 3 4 5
    estrapolando i clienti esempio 1 2 3 4 5 6 7 8

    significa nel mio caso che gli elementi 1 2 3 4 5 sono sia clienti che fornitori.

    Il valore differenza 6 7 8 mi costituisce quelli che sono i clienti non fornitori.

    Da qui mi serve una variabile che mi da' 6 7 8.
    E' chiaro che ci sarebbero vari modi per farlo, purtroppo per altre ragioni devo seguire solo questa strada.

    Bel giro di parole ma questo e' il succo spero che sia chiaro e grazie comunque.


  • User Attivo

    Ciao

    $idfornitori adesso è una variabile che si sostituisce ad ogni ciclo del while. Se tu ci aggiungi le parentesi quadre, facendolo diventare $idfornitori[], lo consideri un array a cui accodi un valore alla fine ad ogni esecuzione del ciclo. La stessa cosa per $idclienti. Arrivato alla fine, la tua variabile sarà appunto $var = array_diff($idfornitori, $idclienti).


  • User Attivo

    Ciao ancora Francesco e scusami, ho provato purtroppo non stampa nulla, potresti continuare sotto le query scrivendo quello che hai detto sopra? Te le riposto:

    $query1 = "SELECT * FROM tab1 WHERE localita='Napoli'";
    $result1 = mysql_query($query1,$link);
    if(mysql_num_rows($result1)){
    while($row = mysql_fetch_array($result1)){
    $idfornitori=stripslashes($row["id"]);

    $query2 = "SELECT * FROM tab2 WHERE localita='Napoli'";
    $result2 =mysql_query($query2, $link);
    if(mysql_num_rows($result2)){
    while($row = mysql_fetch_array($result2)){
    $idclienti=stripslashes($row["id"]);

    da qui fino alla differenza tra le variabili se possibile.Grazie mille.


  • User Attivo

    Ciao,

    [php]
    <?php
    $idfornitori = array();$idclienti = array();
    $query1 = "SELECT * FROM tab1 WHERE localita='Napoli'";
    $result1 = mysql_query($query1, $link);
    if (mysql_num_rows($result1)) {
    while ($row = mysql_fetch_array($result1)) {
    $idfornitori[] = stripslashes($row["id"]);
    $idfornitore = stripslashes($row["id"]);
    // fai il resto delle tue operazioni
    }
    $query2 = "SELECT * FROM tab2 WHERE localita='Napoli'";
    $result2 = mysql_query($query2, $link);
    if (mysql_num_rows($result2)) {
    while ($row = mysql_fetch_array($result2)) {
    $idclienti[] = stripslashes($row["id"]);
    $idcliente = stripslashes($row["id"]);
    // fai il resto delle tue operazioni
    }
    }
    }
    $differenza = array_diff($idclienti, $idfornitori);
    ?>
    [/php]

    Ti ho messo due variabili diverse: $idcliente e $idfornitore (al singolare) contiene solo l'id che stai prendendo in considerazione in quel momento, mentre $idclienti ed $idfornitori sono due array che alla fine dei while li contengono tutti. La differenza con array_diff() la faccio dopo entrambi i while. Questo per fare in modo che se nei while ti serve l'id del singolo, ce l'hai a disposizione.

    Mi sembra di capire che stai imparando, quindi mi permetto di sollevare un dubbio... stripslashes() su un id? Che id è?


  • User Attivo

    No France' e' solo un copia incolla e poi ho cambiato i valori nelle parentesi senza curare i particolari, ora provo lo script e ti faccio sapere grazie sempre gentile.


  • User Attivo

    Ciao France' , nnte quando provo a stampare $differenza mi stampa "Array", pero' la differenza la fa perche' il numero di volte che esce "Array" e' pari al numero di id che dovrebbe uscire.
    Quando ottengo questa differenza a sua volta la devo riutilizzare in un'altra query.


  • User Attivo

    E' normale, un'array non si stampa con echo(). Se vuoi stampare i numeri in formato 1 2 3 4 5 6 7, cioè separati da spazi, ti basta fare

    [php]
    <?php
    foreach($differenza as $elemento) echo $elemento." ";
    ?>
    [/php]

    Le funzioni per stampare gli array in output con la formattazione standard di php sono print_r() e var_dump()

    EDIT: aspetta, che significa la devi riutilizzare in un'altra query? Fammi capire con che formattazione ti serve e così ti dico.


  • User Attivo

    Ah ecco, gli array li faro' tra un po' quindi nn lo sapevo. Tutto ok la diff e' fatta:
    Allora la riga che hai poststo,
    <? foreach($diff as $elemento) echo $elemento;?> mi stampa gli elementi differenza, cosi' anche senza spazi xche mi serve nella query successiva per richiamare i valori associati a quegli id e funziona benissimo. Il problema ora e' che quando stampo per prova usando la tua riga, stampa correttamente gli id differenza, ma quando porto $elemento (che dovrebbe essere gia' formattato come mi serve perche' del tipo 12345) nella query mi tira fuori un id che non risulta nella differenza, quindi mi stampa un record in piu' che non c'entra nulla con la differenza; e questo per me e' un notevole mistero.
    Essendo $elemento l'insieme dei valori differenza:
    -In che altro modo posso portarmelo nella query ?
    -Necessita di un ulteriore formattazione?
    -Oppure ho fatto qualche altra cappellata?
    Penso piu' la terza 😞


  • User Attivo

    Non considerando piu' il post precedente, ti ringrazio per la dritta,
    ci sono riuscito , ma non va bene perche non ho considerato una cosa da idiota.
    Sarebbe meglio usare FORSE una funzione del tipo in_array nel senso che :

    se nell' array A sono presenti valori contenuti nell'array B allora vengono eliminati e stampa solo A perche' in B puo' esserci uno o piu elementi non contenuti in A e in quel caso li calcola nella differenza ma non ci devono essere.
    Il succo e' che i valori di B non devono proprio figurare a prescindere se siano presenti in A o meno, mi serve solo A senza EVENTUALI valori uguali a quelli di B.
    La formattazione puo essere del tipo 12345 senza problemi xche li devo poi usare nella query che mi estrapola i record degli id di A che risultano.


  • User Attivo

    @Piterrey said:

    Il succo e' che i valori di B non devono proprio figurare a prescindere se siano presenti in A o meno, mi serve solo A senza EVENTUALI valori uguali a quelli di B.

    Ritorniamo punto e a capo, array_diff() fa proprio questo:

    [php]
    <?php
    $a = array();
    // riempi $a coi risultati di una query
    $b = array();
    // riempi $b coi risultati di una query
    $c = array_diff($a, $b);
    // $c contiene tutti i valori di $a meno quelli che sono anche in $b
    ?>
    [/php]

    @Piterrey said:

    La formattazione puo essere del tipo 12345 senza problemi xche li devo poi usare nella query che mi estrapola i record degli id di A che risultano.

    Cosa ti frega della formattazione se poi devi utilizzarli per una query da cui devi estrarre dei record? Un array è esattamente quello che ti serve, la formattazione ti interessa quando devi stamparli. Proseguendo l'esempio di prima:

    [php]
    foreach ($c as $elemento) {
    $sql = "SELECT * FROM tabella WHERE id = '$elemento'";
    $query = mysql_query($sql);
    $record = mysql_fetch_array($query);
    // $record ora contiene un array associativo con tutti gli elementi delle colonne di della tabella
    // lo puoi dunque stampare
    echo $record["id"];
    echo $record["partita_iva"];
    echo $record["nome"];
    // e così via
    }
    ?>
    [/php]

    il foreach si ripete per tutti gli elementi di $c che, appunto, sono tutti quelli di $a meno quelli presenti in $b.


  • User Attivo

    Ciao Francesco sembra quasi che non me ne esco piu', mi stampa elementi che non ci dovrebbero essere e non capisco perche'
    ti posto tutta la logica applicata in modo diverso e senza clienti forse andiamo meglio.(ora che ci penso potrebbe essere la stessa logica di un codice che genera gli amici degli amici in facebook)

    <?php
    $query = "SELECT * FROM users INNER JOIN...fornitori on.............. where id='$userid'"; // selezione dei miei fornitori in base al mio $userid
    $result = mysql_query($query, $link);
    while($row = mysql_fetch_array($result)){
    $idfornitori= $row["id"]; //ottengo l'insieme $idfornitori //
    $query1 = "SELECT * FROM users INNER JOIN .......fornitori on.............. where id='$idfornitori'";// da cui giocando coi risultati ricavo id di altri fornitori che forniscono i miei fornitori //
    $result1 = mysql_query($query1, $link);
    while($row = mysql_fetch_array($result1)){
    $idfornitori_dei_fornitori= $row["id"]; //ottengo l'insieme di quelli che forniscono i miei fornitori, ma qualcuno di essi potrebbe fornire anche me per cui lo devo escludere//

    //da qui devo ottenere quindi la famosa variabile differenza ( e' come estrarre gli id degli amici dei miei amici ma qualcuno potrebbe essere anche amico mio, cosi' per i fornitori dei miei fornitori e qualcuno potrebbe fornire anche me (l'esempio calza).chiaramente ho bisogno di vedere solo i fornitori dei miei fornitori e non quelli che gia conosco.
    in piu' non le ho controllate , se mi dai un occhio anche alle parentesi.// e scusami ancora.

    ?>


  • User Attivo

    Non ne usciamo perché, ahimé, non vuoi comprendere la differenza tra variabile ed array. 😄

    Con il codice così come l'hai impostato nel precedente post, tu non prendi affatto gli ID dei fornitori, o meglio li prendi anche, ma li perdi tutti per strada, memorizzando solo l'ultimo estratto nelle variabili $id_fornitori e $idfornitori_dei_fornitori. Questo perché dopo quelle due variabili non metti le due parentesi quadre vuote [] che significano appunto "questo è un array, ed il valore che gli sto assegnando devi piazzarlo all'ultimo posto".
    Dal momento in tu piazzi le due parentesi quadre dopo quei nomi di variabili, in $idfornitori avrai sul serio l'insieme dei fornitori ed in $idfornitori_dei_fornitori avrai sul serio l'insieme dei fornitori dei fornitori.

    Arrivato a quel punto, se tu vuoi escludere da $idfornitori quelli presenti in $idfornitori_dei_fornitori:

    $differenza = array_diff($idfornitori, $idfornitori_dei_fornitori);

    mentre se vorrai fare il contrario, ossia escludere da $idfornitori_dei_fornitori i valori in $idfornitori:

    $differenza = array_diff($idfornitori_dei_fornitori, $idfornitori);

    tutto dipende dall'ordine in cui li metti in array_diff.

    $differenza sarà un array di valori, quindi per scorrerlo dovrai utilizzare il foreach() come ti ho mostrato nel mio post precedente.
    Se non ti è chiaro, ti rimane solo una cosa da fare:

    • spiega in modo chiaro quali sono le due tabelle e quali valori ottieni da esse
    • fai un esempio chiaro dei valori che devono contenere $idfornitori e $idfornitori_dei_fornitori
    • spiega in modo chiaro cosa devi farci con quelle due serie di valori una volta che li hai ottenuti
    • spiega lo scopo che vuoi raggiungere alla fine di tutto l'ambaradan

    arrivati a quel punto potrò scriverti uno snippet di codice e spiegarti riga per riga cosa fa, perché la mia impressione è che determinate indicazioni tu non le riesca a seguire a causa di una mancanza di conoscenze di base.