Gelijke woorden uit 2 strings halen
Ik heb een veld bucket_old en een veld bucket_new in mijn database. Ik roep deze aan met:
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:
De gelijkenis tussen beiden is nu test1 als resultaat.
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:
De gelijkenis tussen beiden is nu test1 als resultaat.
Je zou van beide strings een array kunnen maken dmv de functie explode() en dan de overeenkomsten in deze arrays achterhalen dmv array_intersect()
Mijn eerste probleem begint al met dit:
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?
Code (php)
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
foreach ($arr222 as $val122) {
$test = $val122. ' ';
//echo $tt;
$str1 = explode(' ', $test);
print_r($str1);
}
$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
Ik snap niet helemaal wat je aan het doen bent?
Volgens mij kun je het hier mee doen:
edit/toevoeging:
die spatie (of lege waarde?) op het eind: kan het zijn dat de string die je explode, eindigt met een komma?
Volgens mij kun je het hier mee doen:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
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 />';
}
?>
$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
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?
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
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:
Dit werkt in ieder geval:
Code (php)
1
2
3
4
5
6
7
8
9
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 />';
}
$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
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.
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.
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.
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 :)
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?
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
ofwel zijn de id's verschillend ofwel zet je er een extra kolom bij met een 1 of 2 voor old / new
Ok. Ik zal dit eerst aanpassen en kom er dan op terug.
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.
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.
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:
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?
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)
1
2
3
4
5
6
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
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)
1
2
3
4
5
6
7
8
9
10
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 />';
}
?>
$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
Dat hoeft niet, je kan dat de database laten doen met een self_join:
Dit is een query voor de tabel opbouw zoals ik hem zou maken.
Code (php)
1
2
3
4
5
6
7
8
9
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
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
je tabel zou er voor Ger's query dan uit moeten zien als
@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
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.
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.
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.
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.
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)
1
2
3
4
5
6
7
8
9
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
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
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).
Dit is niet de fijnste querie, en als ik zelf zulke queries nodig zou hebben, zou ik me eens flink achter de oren krabben!
Code (php)
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
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
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
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.
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
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.
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.




