Gelijke woorden uit 2 strings halen

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Pagina: 1 2 volgende »

Brecht S

Brecht S

04/02/2015 19:41:01
Quote Anchor link
Ik heb een veld bucket_old en een veld bucket_new in mijn database. Ik roep deze aan met:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
$bucket_old = $row['bucket_old'];
$bucket_new = $row['bucket_new'];


De waarden die in beide zitten zijn gescheiden woorden met een komma, vb: test,test2,test3,test4
Hoe kan ik nu uit beide strings de gelijke woorden halen?
Even een voorbeeld ter verduidelijking:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
$bucket_old = "test1,test2";
$bucket_new = "test3,test1";

De gelijkenis tussen beiden is nu test1 als resultaat.
 
PHP hulp

PHP hulp

21/11/2024 22:37:39
 
Frits Katoen

Frits Katoen

04/02/2015 20:00:00
Quote Anchor link
Je zou van beide strings een array kunnen maken dmv de functie explode() en dan de overeenkomsten in deze arrays achterhalen dmv array_intersect()
 
Brecht S

Brecht S

04/02/2015 22:06:05
Quote Anchor link
Mijn eerste probleem begint al met dit:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
foreach ($arr222 as $val122) {

$test = $val122. ' ';
//echo $tt;
$str1 =  explode(' ', $test);
print_r($str1);

}

Dit geeft mij al resultaat: Array ( [0] => ecc391cc90 [1] => ) Array ( [0] => c220295e09 [1] => )
Alhoewel de waarde $test wel dit geeft: ecc931cc90 c220295e09
Op het einde van de string heb ik wel een spatie staan, vandaar die [1] => SPATIE
Hoe krijg ik dit goed?
Gewijzigd op 04/02/2015 22:12:44 door Brecht S
 
Frits Katoen

Frits Katoen

04/02/2015 23:52:43
Quote Anchor link
Ik snap niet helemaal wat je aan het doen bent?

Volgens mij kun je het hier mee doen:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
<?php
$arr1
= explode(',',$bucket_old);
// $arr1 is nu een array met de waarden->array('test1','test2')
$arr2 = explode(',',$bucket_new);
// $arr2 is nu een array met de waarden->array('test3','test1')
$arrGelijk = array_intersect($arr1, $arr2); // vind de gelijke waarden in beide array's
//print de array met gelijke waarden

foreach($arrGelijk as $waarde){
    echo $waarde.'<br />';
}

?>


edit/toevoeging:
die spatie (of lege waarde?) op het eind: kan het zijn dat de string die je explode, eindigt met een komma?
Gewijzigd op 04/02/2015 23:56:19 door Frits Katoen
 
Brecht S

Brecht S

05/02/2015 00:06:09
Quote Anchor link
Ja inderdaad. Dat is de string die eindigde met een komma.
Als ik jouw code uitprobeer krijg ik het probleem dat ik hierboven heb beschreven. Ik weet niet hoe het komt.
Waarom heb ik 2 array's achter elkaar?
Gewijzigd op 05/02/2015 00:09:05 door Brecht S
 
Frits Katoen

Frits Katoen

05/02/2015 18:18:59
Quote Anchor link
wil je eens een var_dump() doen van $bucket_old en van de variabele die je met explode() aanmaakt? Ben wel benieuwd wat daar in staat want anders zou het gewoon moeten werken.

Dit werkt in ieder geval:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
<?php
$str1
= 'test1,test2,test3,test4';
$str2 = 'test1,test4,test5,test6';
$arr1 = explode(',',$str1);
$arr2 = explode(',',$str2);
$arrGelijk = array_intersect($arr1, $arr2);
foreach($arrGelijk as $waarde){
    echo $waarde.'<br />';
}
Gewijzigd op 05/02/2015 18:19:17 door Frits Katoen
 
Ivo P

Ivo P

05/02/2015 18:43:29
Quote Anchor link
het hele probleem zou niet bestaan, als je de data genormaliseerd zou hebben opgeslagen:

een losse tabel waarin alle woorden los opgeslagen staan, voorzien van een id dat verwijst naar je record in de andere tabel.

Misschien kost dat nu wat ombouw, of mogelijk kost het je een uurtje extra om te snappen hoe dat te doen,

maar aan de andere kant is bovengenoemd gepuzzel met array's dan ineens in een vrij simpele query te regelen.
 
Frits Katoen

Frits Katoen

05/02/2015 18:57:24
Quote Anchor link
Ivo P op 05/02/2015 18:43:29:
het hele probleem zou niet bestaan, als je de data genormaliseerd zou hebben opgeslagen:

een losse tabel waarin alle woorden los opgeslagen staan, voorzien van een id dat verwijst naar je record in de andere tabel.

Misschien kost dat nu wat ombouw, of mogelijk kost het je een uurtje extra om te snappen hoe dat te doen,

maar aan de andere kant is bovengenoemd gepuzzel met array's dan ineens in een vrij simpele query te regelen.


Amen :)
 
Brecht S

Brecht S

05/02/2015 19:12:13
Quote Anchor link
Ik heb 2 strings. bucket_old en bucket_new. Ik zal de woorden in deze 2 tabellen apart opslaan en dan kom ik er op terug. Of kan ik het ook in 1 tabel?
 
Ivo P

Ivo P

05/02/2015 20:10:18
Quote Anchor link
1 tabel zou voldoende moeten zijn.

ofwel zijn de id's verschillend ofwel zet je er een extra kolom bij met een 1 of 2 voor old / new
 
Brecht S

Brecht S

05/02/2015 20:16:47
Quote Anchor link
Ok. Ik zal dit eerst aanpassen en kom er dan op terug.
 
Thomas van den Heuvel

Thomas van den Heuvel

05/02/2015 20:32:44
Quote Anchor link
Is het geen optie om je emmers eerst gewoon helemaal leeg te maken, en dan opnieuw te vullen? :)

Dat doe je meestal ook met koppeltabellen.

Bijvoorbeeld user A heeft een koppeling met id's 1, 2, en 3.

Als je je gegevens wijzigt zodat user A na afloop een koppeling heeft met id's 2 en 4, dan is het gewoon veel simpeler om eerst alle verbanden met user A te verwijderen en daarna weer (opnieuw) toe te voegen.

Tenzij je een speciale reden hebt om onderscheid te maken tussen de volgende gevallen:
id 1: voor JA, na NEE
id 2: voor JA, na JA
id 3: voor JA, na NEE
id 4: voor NEE, na JA

Als er geen reden is, is er ook geen reden om zo moeilijk te doen.
 
Brecht S

Brecht S

06/02/2015 10:49:46
Quote Anchor link
Ja ik heb een goede reden om die 2 (voor en na) op te slaan. Omdat ik die nodig heb om users te subscriben en te unsubscriben. Ook de gelijke woorden in beide strings heb ik nodig omdat de users zijn die moeten blijven staan in de lijsten. De andere (de verschillen die niet in beide voorkomen) moeten ofwel ingeschreven of uitgeschreven worden afhankelijk of ze het voor of na 'label' meekrijgen.

Ondertussen heb ik voor zowel de old als de new de data opgeslagen in de database. Iedere keer delete ik die items terug van beide kanten zodat ik altijd de laatste updates heb.
Mijn tabel ziet er nu als volgt uit:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
ID    old             new            contact_id
1     ecc7894rty                     1154
2     rty8885rez                     1154
3                     ecc7894rty     1154
4                     rty8885rez     1154
5                     poi5412oop     1154


Dit is nu bvb van 1 user. Er zullen dus meerdere users in de lijst komen te staan maar telkens met de juiste geupdate gegevens.
Nu moet ik de verschillen kunnen vinden. Over naar stap 2.

Ik vermoed om volgende code toe te passen dat ik nu str1 en str2 zal moeten opbouwen met gegevens uit de database. Hoe doe ik dit het best?
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
<?php
$str1
= 'test1,test2,test3,test4';
$str2 = 'test1,test4,test5,test6';
$arr1 = explode(',',$str1);
$arr2 = explode(',',$str2);
$arrGelijk = array_intersect($arr1, $arr2);
foreach($arrGelijk as $waarde){
    echo $waarde.'<br />';
}

?>
Gewijzigd op 06/02/2015 12:28:49 door Brecht S
 
Ger van Steenderen
Tutorial mod

Ger van Steenderen

06/02/2015 13:31:41
Quote Anchor link
Dat hoeft niet, je kan dat de database laten doen met een self_join:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
SELECT o.contact_id,
    o.old_new_value
FROM old_new o
JOIN old_new n
    ON o.contact_id = n.contact_id
    AND o.old_new_value = n.old_new_value
    AND n.type = 1
WHERE
    o.type = 0

Dit is een query voor de tabel opbouw zoals ik hem zou maken.
Gewijzigd op 06/02/2015 13:36:55 door Ger van Steenderen
 
Ivo P

Ivo P

06/02/2015 13:35:11
Quote Anchor link
je tabel zou er voor Ger's query dan uit moeten zien als
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
ID    old_new_value contact_id  type
1     ecc7894rty     1154        0
2     rty8885rez     1154        0
3     ecc7894rty     1154        1
4     rty8885rez     1154        1
5     poi5412oop     1154        1
 
Brecht S

Brecht S

06/02/2015 15:13:18
Quote Anchor link
@Ger en Ivo: ik heb mijn volledige code aangepast naar jouw idee en dat werkt nu goed. Ik wist niet dat je ook een JOIN kon doen op dezelfde tabel, ik dacht dat dit altijd met een andere tabel was. Nu moet ik alleen nog een oplossing vinden om ieder listID (ecc7894abc bvb) apart te versturen. Nu zit dit in een while. Moest dit nu niet lukken kom ik hier nog even op terug straks. Eerst eens zelf proberen ;-)
Gewijzigd op 06/02/2015 15:14:27 door Brecht S
 
Thomas van den Heuvel

Thomas van den Heuvel

06/02/2015 16:44:33
Quote Anchor link
Is het een optie om iemand eerst te unsubscriben en dan te re-subscriben?

Als dat niet het geval is dan is er reden te meer om die subscriptions uit elkaar te trekken lijkt mij, dan kun je die namelijk per geval behandelen, in plaats van alles elke keer volledig te inspecteren en te vergelijken.
 
Brecht S

Brecht S

06/02/2015 16:56:44
Quote Anchor link
Nee, dat is geen optie. Als ik mensen eerst unsubscribe en dan terug re-subscribe dan ben ik die persoon zijn statistieken kwijt. Dus ik moet het doen met de verschillen tussen beiden.

Dus ik heb nu wel de gelijkenissen in beiden, maar ik moet ook de verschillen hebben. Ik zal dus een nieuwe query nodig hebben gebaseerd op degene ik nu al heb.
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
SELECT o.contact_id,
    o.old_new_value
FROM old_new o
JOIN old_new n
    ON o.contact_id = n.contact_id
    AND o.old_new_value = n.old_new_value
    AND n.type = 1
WHERE
    o.type = 0


Toevoeging op 06/02/2015 17:25:50:

Ik heb geprobeerd van die ene regel AND o.old_new_value = n.old_new_value te veranderen in AND o.old_new_value <> n.old_new_value maar dat werkt dus niet. Ik krijg andere resultaten.
Gewijzigd op 06/02/2015 16:59:07 door Brecht S
 
Ger van Steenderen
Tutorial mod

Ger van Steenderen

06/02/2015 18:35:48
Quote Anchor link
Je moet niet de voorwaarden omdraaien, maar het join type, maw van de inner join een outer join maken, en dan AND n.contact_id IS NULL aan de where clause toevoegen (aka de anti-join).
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
SELECT o.contact_id,
    o.old_new_value,
    'keep' todo
FROM old_new o
JOIN old_new n
    ON o.contact_id = n.contact_id
    AND o.old_new_value = n.old_new_value
    AND n.type = 1
WHERE
    o.type = 0

UNION

SELECT o.contact_id,
    o.old_new_value,
    'kick' todo
FROM old_new o
LEFT JOIN old_new n
    ON o.contact_id = n.contact_id
    AND o.old_new_value = n.old_new_value
    AND n.type = 1
WHERE
    o.type = 0 AND n.contact_id IS NULL

UNION

SELECT o.contact_id,
    o.old_new_value,
    'welcome' todo
FROM old_new o
LEFT JOIN old_new n
    ON o.contact_id = n.contact_id
    AND o.old_new_value = n.old_new_value
    AND n.type = 0
WHERE o.type = 1 AND n.contact_id IS NULL
ORDER BY contact_id, old_new_value

Dit is niet de fijnste querie, en als ik zelf zulke queries nodig zou hebben, zou ik me eens flink achter de oren krabben!
Gewijzigd op 06/02/2015 18:37:53 door Ger van Steenderen
 
Brecht S

Brecht S

06/02/2015 18:49:37
Quote Anchor link
Wat bedoel je met 'kick' todo en 'welcome' todo, ... ? Hier kan ik niet volgen.
Hoef ik deze 3 query's in een union te gebruiken of kan ik ze ook afzonderlijk gebruiken?

Als ik de (inner) JOIN verander in een OUTER JOIN werkt de query niet meer.
Gewijzigd op 06/02/2015 18:55:32 door Brecht S
 
Ger van Steenderen
Tutorial mod

Ger van Steenderen

06/02/2015 19:07:51
Quote Anchor link
De todo 'kolom' gebruik ik om te weten uit welke query de waarde komt.
Natuurlijk kan je de drie queries ook afzonderlijk draaien.

Een outer join kan een left of right outer join zijn, het outer keyword is optioneel.

Maar ik begrijp nog steeds niet waar je allemaal mee bezig bent, ik kan geen enkele logica vinden in deze manier van gegevens opslaan.
 

Pagina: 1 2 volgende »



Overzicht Reageren

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.