Hoe kan ik arrays vergelijken in een loop en samenvoegen wanneer gelijk

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Snelle Jaap

Snelle Jaap

15/01/2020 11:54:29
Quote Anchor link
Ik heb een sessie (array) met producten. Als een product nu twee keer wordt toegevoegd met precies dezelfde waardes wordt hij ook twee keer in de array gezet.

Ik moet hebben dat hij dubbele arrays samenvoegt en alleen 'aantal' bij elkaar optelt a.d.h.v. het aantal dubbele arrays.

Hoe kan ik dit doen?

Dit is bijvoorbeeld zo'n array:

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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
array(
    [0] => array(
            [productnaam]       => Monomeer
            [basisprijs]        => 0
            [basisstaffel]      => 0-3:23;3-10:17;10-20:14;20-30:12;30-40:10;40-50:7,50;50-60:6,50;60-110:6;
            [minimaalformaat]   => 10x3
            [maximaalformaat]   => 120x5000
            [breedte]           => 100
            [hoogte]            => 30
            [aantal]            => 1
            [Lijmlaag]          => Wit(prijsberekening)($m2*4);
            [Laminaat]          => Anti-slip laminaat(prijsberekening)($o*5);
            [Afwerking]         => Contoursnijden(prijsberekening)($m2*30);
            [extra] => Array(
                    [Elastieken|4,50] => 0
                    [Tiewraps|9,95] => 0
                )
        )    
    [1] => array(
            [productnaam]       => Monomeer
            [basisprijs]        => 0
            [basisstaffel]      => 0-3:23;3-10:17;10-20:14;20-30:12;30-40:10;40-50:7,50;50-60:6,50;60-110:6;
            [minimaalformaat]   => 10x3
            [maximaalformaat]   => 120x5000
            [breedte]           => 10
            [hoogte]            => 3
            [aantal]            => 1
            [Lijmlaag]          => Wit(prijsberekening)($m2*4);
            [Laminaat]          => Anti-slip laminaat(prijsberekening)($o*5);
            [Afwerking]         => Contoursnijden(prijsberekening)($m2*30);
            [extra] => Array (
                    [Elastieken|4,50] => 0
                    [Tiewraps|9,95] => 0
                )
        )

    [2] => array(
            [productnaam]       => Monomeer
            [basisprijs]        => 0
            [basisstaffel]      => 0-3:23;3-10:17;10-20:14;20-30:12;30-40:10;40-50:7,50;50-60:6,50;60-110:6;
            [minimaalformaat]   => 10x3
            [maximaalformaat]   => 120x5000
            [breedte]           => 10
            [hoogte]            => 3
            [aantal]            => 1
            [Lijmlaag]          => Wit(prijsberekening)($m2*4);
            [Laminaat]          => Anti-slip laminaat(prijsberekening)($o*5);
            [Afwerking]         => Contoursnijden(prijsberekening)($m2*30);
            [extra] => Array(
                    [Elastieken|4,50] => 0
                    [Tiewraps|9,95] => 0
                )
        )
)


Dat zou dus uiteindelijk dit resultaat moeten zijn:

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
array(
    [0] => array(
            [productnaam]       => Monomeer
            [basisprijs]        => 0
            [basisstaffel]      => 0-3:23;3-10:17;10-20:14;20-30:12;30-40:10;40-50:7,50;50-60:6,50;60-110:6;
            [minimaalformaat]   => 10x3
            [maximaalformaat]   => 120x5000
            [breedte]           => 100
            [hoogte]            => 30
            [aantal]            => 1
            [Lijmlaag]          => Wit(prijsberekening)($m2*4);
            [Laminaat]          => Anti-slip laminaat(prijsberekening)($o*5);
            [Afwerking]         => Contoursnijden(prijsberekening)($m2*30);
            [extra] => Array(
                    [Elastieken|4,50] => 0
                    [Tiewraps|9,95] => 0
                )
        )    
    [1] => array(
            [productnaam]       => Monomeer
            [basisprijs]        => 0
            [basisstaffel]      => 0-3:23;3-10:17;10-20:14;20-30:12;30-40:10;40-50:7,50;50-60:6,50;60-110:6;
            [minimaalformaat]   => 10x3
            [maximaalformaat]   => 120x5000
            [breedte]           => 10
            [hoogte]            => 3
            [aantal]            => 2
            [Lijmlaag]          => Wit(prijsberekening)($m2*4);
            [Laminaat]          => Anti-slip laminaat(prijsberekening)($o*5);
            [Afwerking]         => Contoursnijden(prijsberekening)($m2*30);
            [extra] => Array (
                    [Elastieken|4,50] => 0
                    [Tiewraps|9,95] => 0
                )
        )
)


Waar moet ik beginnen?

Ik zou niet weten hoe ik binnen een loop kan checken op dubbele waardes in de gehele array.

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
foreach($_SESSION['producten'] as $key => $product){

}


Ik had vroeger iets soortgelijks maar die array had namen als keys waar ik op checkte. Dat was deze code:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
// If id of product does not exist, add it to session
if(!isset($_SESSION['producten'][$arr2['productid'].$arr2['kuubkosten']])){
    $_SESSION['producten'][$arr2['productid'].$arr2['kuubkosten']] = $arr2;
// Else add to quantity
}else{
    $_SESSION['producten'][$arr2['productid'].$arr2['kuubkosten']]['quantity'] += $arr2['quantity'];
}
Gewijzigd op 15/01/2020 11:56:29 door Snelle Jaap
 
PHP hulp

PHP hulp

20/04/2024 15:24:14
 
Frank Nietbelangrijk

Frank Nietbelangrijk

15/01/2020 12:36:46
Quote Anchor link
Ik ga er even vanuit dat dit een winkelwagentje betreft. Ik zou enkel die informatie in de sessie zetten die strikt noodzakelijk is. Informatie die je simpel uit de database kunt halen zou ik niet in de sessie zetten.

Doorgaans betekent het dat je enkel het database ID en het aantal in de sessie hoeft te schrijven. Je kunt dan het database ID als array key gebruiken en het aantal als value. Bijvoorbeeld

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
[
    234 => 1,
    435 => 2
]


(aantal 1 en aantal 2)
Aan de hand van je database ID kun je nu kijken of deze al in de array zit
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
<?php
if(isset($cart[$product_id])) {
    $cart[$product_id]++;
}
else {
    $cart[$product_id] = 1;
}

?>


Toevoeging op 15/01/2020 12:43:33:

In elk geval staat er nu in je sessie geen enkele unieke identificatie. Dus hoe moet je dan weten wat wat is?
 
Snelle Jaap

Snelle Jaap

15/01/2020 12:53:46
Quote Anchor link
Als een product nu twee keer wordt toegevoegd met precies dezelfde gegevens zou hij dubbel in de winkelmand staan. Dat is niet hoe het uiteindelijk moet. Alleen als de gegevens van het product uniek zijn heeft hij zijn eigen positie in de winkelmand.

Voorbeeld:

Product1 - kleur rood
Product1 - kleur blauw

^ Staan alletwee in de winkelmand

Product1 - kleur rood
Product1 - kleur rood

^ Wordt samengevoegd tot 1, waarbij het aantal van Product1 2 is.
 
Frank Nietbelangrijk

Frank Nietbelangrijk

15/01/2020 13:08:30
Quote Anchor link
Er zijn natuurlijk houtje-touwtje oplossingen zoals alle elementen in een array met elkaar vergelijken maar de basis is niet juist voor hetgeen je wil. Zoals je zelf al aangaf en ik ook zou je een unieke identifier moeten hebben voor ieder product. Daarnaast zou je voor de opties die je nu laat zien zoals de kleur hetzelfde kunnen doen. maar het begint met het vergelijken van is product A gelijk aan product B en hiervoor gebruik je gewoon een unique ID.
 
Snelle Jaap

Snelle Jaap

15/01/2020 14:03:17
Quote Anchor link
Het gaat voor mij echt puur om de gegevens. Als ik een uniek id geef aan een product en deze twee keer toevoeg met verschillende (voorbeeld) kleuren, hebben beide nog steeds hetzelfde id en kan ik er nog niks mee.
 
Ozzie PHP

Ozzie PHP

15/01/2020 14:28:46
Quote Anchor link
En dus moet je zowel het rode als het blauwe product een eigen ID geven, zoals door Frank reeds gezegd.

Een zwarte Ferrari is iets anders dan een rode Ferrari. Beiden hebben dan ook hun eigen productnummer.

Het verschil in productnummer kan bijv. ook zitten in een toevoeging.

ABC123-B is zwart (black)
ABC123-R is rood (red)
 
Ivo P

Ivo P

16/01/2020 10:11:42
Quote Anchor link
desnoods verbind je een aantal id's met elkaar:

een Ferrari = product abc123
zwart is kleur-id 1
en brandstof-id voor Benzine id 2

en je wilt er 3 stuks

$aProduct['abc123;1;2'] = 3
 
Ward van der Put
Moderator

Ward van der Put

16/01/2020 11:53:20
Quote Anchor link
Dit lijkt me een situatie waarin je de weergave van een totaal toch los moet (blijven) zien van de samenstellende delen. Je kunt wel 2 rode en 1 zwarte weergeven als 3, maar bij het produceren of inpakken van de order moeten die 3 weer worden uitgesplitst in 2 rode en 1 zwarte.
 
Paul Balen

Paul Balen

16/01/2020 18:18:35
Quote Anchor link
Wat ik hier zie en lees zeg ik vergeet je arrays. Zo als de meeste hier al schrijven gebruik voor elk product een uniek ID. Oftewel je zult hier eerst een wel overdachte database met de juiste tabellen moeten bedenken .
Voorbeeld zoals ik het zou doen is dat er in de database een tabel klanten staat, een tabel bestellen en een tabel producten. In een tabel al je producten met ieder een uniek ID, In de tabel klanten elke klant een uniek ID en tot slot in je tabel bestellen een kolom waar klant id in komt en een kolom product id, daarnaast aantal , dit is pure basis wat ik schrijf maar dan kun je koppelen per klant het aantal per product. Wat heel handig is om een tabel bonnen te maken of een andere duidelijke naam, waar je alles weer in opslaat zodra er betaald is. Op deze manier kun je aan het eind van een periode duidelijk zien welke artikelen wel of niet goed lopen en wat je verdiend hebt. Het is maar een voorbeeld maar ik zou als ik jou was je proces omgooien naar een degelijke database.
Gewijzigd op 16/01/2020 18:19:52 door Paul Balen
 
Thomas van den Heuvel

Thomas van den Heuvel

17/01/2020 15:10:30
Quote Anchor link
Okay, waar te beginnen.

Een product (bijvoorbeeld: Metallica t-shirt) heeft vaak meerdere uitvoeringen: verschillende maten, kleuren en andere eigenschappen. Deze unieke eigenschap-configuraties leveren uiteindelijk gezamenlijk concrete producten. Een "Metallica t-shirt" is dus meer een soort van verzamelnaam voor de verschillende uitvoeringen. Een "Metallica t-shirt" an sich bestaat niet als concreet product. Een "Metallica t-shirt" maat XL met V-hals, lange mouwen en kleur zwart is wel een voorbeeld van een concreet/fysiek product.

Indien je je database echt generiek wilt opzetten ten aanzien van producten, dan zou je dus tabellen moeten hebben voor:
- de producten (de kapstok van het product)
- de uitvoeringen van een product (de kapstok van de eigenschappen)
- de eigenschappen die bij een uitvoering horen (of liever gezegd, de specifieke eigenschap-waarden)
- de toegestane waarden voor die eigenschappen
- en alle koppeltabellen die hiertussen zitten

Schematisch wordt dat dus zoiets:
Afbeelding
Uiteraard zijn hier vele varianten op mogelijk, bovenstaande afbeelding schetst enkel de mogelijke verbanden.

En dan zijn er mogelijk nog vrij in te vullen velden zoals afmetingen (of zijn dit standaard maten?) zoals in het oorspronkelijke bericht. Deze liggen dan niet op voorhand vast in een specifieke uitvoering.

Anyhow, terug naar de producten in kwestie. Ik weet niet of dit te vangen is in het bovenstaande stramien, of dat je dan te maken krijgt met een explosie aan mogelijke configuraties? Voor een database maakt dit niet zoveel uit hoeveel dit er zijn. Dus waar je meer naar zou moeten kijken is hoe je dit toegankelijk maakt/ontsluit voor potentiële kopers. Je zou hiervoor een facetted search of een soort van product wizard kunnen maken waarbij de klant snel kan inzoomen naar wat deze precies zoekt. En dan vervolgens nog vrij in te vullen velden in kan geven zoals afmetingen ofzo. Vergelijk dit met zoekfunctionaliteit op electronica-sites. Als je zoekt naar een monitor dan selecteer je meestal eerst de rubriek hardware, dan monitoren, en dan heb je meestal filters voor afmetingen, verversingsgraad, merk, resolutie, prijs et cetera. Zoiets zou je ook kunnen maken voor de producten in jouw webshop.

En dan dus jouw sessie.

Misschien allereerst het volgende en meest belangrijke: het is niet de bedoeling dat een sessie een soort van rijdend archief is. Hierin dient uitsluitend relevante informatie opgeslagen te worden. Als je dus je productinformatie fatsoenlijk hebt gestructureerd, dan staan er in je sessie uitsluitend een product id, aantal, en eventueel de vrij in te vullen velden in. De rest van de informatie is afleidbaar en hoeft dus niet eindeloos doorgegeven te worden in de sessie.

Met een fatsoenlijke indeling speelt het bovenstaande probleem (de onduidelijkheid of twee producten "hetzelfde" zijn) waarschijnlijk ook niet, omdat je alles al volledig hebt uitgesplitst.

Maar het begint dus (wederom) met een goed ontwerp.
Gewijzigd op 17/01/2020 15:11:32 door Thomas van den Heuvel
 



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.