[php] sommige array-values samenvoegen in nieuwe array

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • PeetR
  • Registratie: Februari 2002
  • Laatst online: 13-09 22:20
Ik loop tegen een probleempje op waar ik maar niet uitkom.

Situatie
Er is een array gevuld met arrays.
PHP:
1
$datalines = array(array(code=>123456,text=>tekst,bla=>blatekst),array(code=>123456,text=>tekst,bla=>andereblatekst),array(code=>124300,text=>tekst,bla=>blatekst));


Wat is de bedoeling?
Als de code gelijk is moet de value van key bla samengevoegd worden in een nieuwe array.
voorbeeld van de nieuwe array:
PHP:
1
$newdata = array(array(code=>123456,text=>tekst,bla=>array(blatekst,andereblatekst)),array(code=>124300, text=>tekst,bla=>blatekst));


Waarom lukt het dan niet?
Dat is inderdaad de vraag. Maar ik heb echt geen idee hoe ik dit aan moet pakken.
'k heb heel php.net over arrays door genomen, maar nog niet tot een oplossing kunnen komen.
Ben bezig geweest met array_keys met search_value, maar die returned dan natuulijk "code". Bovendien, welke searchvalue moet ik dan gebruiken? Ik moet juist de key van de bovenliggende array krijgen. Als ik die heb dan is het wel te doen denk ik.

Your time as a student is the best time of your life


Acties:
  • 0 Henk 'm!

Verwijderd

Lijkt me niet de meest complexe materie ?

Alle datalines doorlopen en controleren of de code al in newdata bestaat, zo ja, merge bla van newdata met bla van datalines, zo nee, voeg nieuw array met code en bla van datalines in.

Acties:
  • 0 Henk 'm!

  • Shagura
  • Registratie: Augustus 2001
  • Laatst online: 14-09 08:25
Ik krijg bij dit soort vreemde array operaties altijd het idee dat de array sowieso veel beter ingedeeld had kunnen worden om mee te beginnen. Bijvoorbeeld door de 'code' als keys te gebruiken zodat je daar veel simpeler hashtable lookups op kan doen. Hij ziet er namelijk nogal vreemd uit op een of andere manier, maar daar kan ik verder ook weinig over zeggen zonder de functie ervan te weten.

Maarja ik had niks te doen en had ik zin om het even te fixen, dus ik heb dit in 10 minuten in elkaar geflanst.
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
37
38
39
40
41
<?php
$datalines = array(
    array(
        'code' => 123456,
        'text' => 'tekst',
        'bla' => 'blatekst'
    ),
    array(
        'code' => 123456,
        'text' => 'tekst',
        'bla' => 'andereblatekst'
    ),
    array(
        'code' => 124300,
        'text' => 'tekst',
        'bla' => 'blatekst'
    )
);

foreach($datalines as $dataline) {
    if (isset($datalinesHelp[$dataline['code']])) {
        $datalinesHelp[$dataline['code']]['text']  = $dataline['text'];
        $datalinesHelp[$dataline['code']]['bla'][] = $dataline['bla'];
    }
    else {
        $datalinesHelp[$dataline['code']] = array(
            'text' => $dataline['text'],
            'bla'  => array($dataline['bla'])
        );
    }
}

foreach($datalinesHelp as $datalineKey => $datalineHelp) {
    if (count($datalineHelp['bla']) == 1)
        $datalineHelp['bla'] = $datalineHelp['bla'][0];
    $newDatalines[] = array('code' => $datalineKey) + $datalineHelp;
}

var_export($newDatalines);

?>

Mja misschien beetje lame om het zo te posten, want zo leer je er ook misschien weinig van. Het zijn gewoon vrij simpele array operaties verder.

[ Voor 4% gewijzigd door Shagura op 04-01-2010 14:58 ]


Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

PeetR: waarom maak je de aanname dat dit zomaar met een standaardfunctie kan en dat je zelf niet hoeft te programmeren? De meeste dingen die je probeert te doen zullen inderdaad met behulp van standaardfuncties makkelijker gaan, maar als je specifieke dingen wil gaan doen met een array zul je daar toch echt zelf een functietje voor moeten schrijven. :)

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • PeetR
  • Registratie: Februari 2002
  • Laatst online: 13-09 22:20
@NMe
zover was ik ook al dat ik zelf iets in elkaar moest zetten :) Wist alleen niet zo goed waar te beginnen :S

@Shagura
Het werkt goed, maar wat je zegt: Op zo'n manier leer ik het zelf nooit. Probeer je code te begrijpen en doorgronden, maar echt een meester in php ben ik ook niet
Om nog even terug te komen op de structuur van de array:
Ik heb een bestand (data.db). Deze heeft een vaste opbouw. Per regel:
PUI(int19),capcode(int7),date,time,longtitude,lattitude,text,captext
als het eerste gedeelte van de PUI gelijk is hoort het bij elkaar. De rest van de regel zal dan ook gelijk zijn op capcode en captext na.
het bestand lees ik in met file() en vervolgens doe ik een explode op ",". Dit levert de array op zoals in de TS versimpeld is weergegeven.
Als er een beter alternatief is dan hoor ik dat natuurlijk graag! (en kom dan niet met: sla je gegevens op in een DB ipv een bestand, want dat is even niet van toepassing)

Your time as a student is the best time of your life


Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 16-09 09:15

Janoz

Moderator Devschuur®

!litemod

Shagura schreef op maandag 04 januari 2010 @ 14:52:
Ik krijg bij dit soort vreemde array operaties altijd het idee dat de array sowieso veel beter ingedeeld had kunnen worden om mee te beginnen.
Ik verwonder me juist altijd over de enorme fixatie op array's die als hashmaps ingezet worden, terwijl er ook al tijden in php een mogelijkheid is om classes (die je dus ook als een soort van structs in kunt zetten) te gebruiken.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

PeetR schreef op maandag 04 januari 2010 @ 15:59:
Het werkt goed, maar wat je zegt: Op zo'n manier leer ik het zelf nooit. Probeer je code te begrijpen en doorgronden, maar echt een meester in php ben ik ook niet
Begrijp je nog specifieke stukken code niet? Nou we toch bezig zijn kunnen we net zo goed andersom werken en het zaakje duidelijk proberen te maken aan de hand van de code in plaats van alles duidelijk te maken zodat je de code zelf kan schrijven zoals we gebruikelijk doen. :P

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • CodeCaster
  • Registratie: Juni 2003
  • Niet online

CodeCaster

Can I get uhm...

Janoz schreef op maandag 04 januari 2010 @ 16:55:
[...]

Ik verwonder me juist altijd over de enorme fixatie op array's die als hashmaps ingezet worden, terwijl er ook al tijden in php een mogelijkheid is om classes (die je dus ook als een soort van structs in kunt zetten) te gebruiken.
Precies, door gebruik te maken van een PUI-klasse in dit geval kun je een constructor maken die een (explode() van een) regel uit je databestand als argument pakt, waarin je vervolgens de code zet die een object instantiëert met als eigenschappen de waarden van die regel, terwijl die code ook de invoer valideert.

Vervolgens kun je van een overkoepelende klasse gebruikmaken die meerdere PUI's bevat, die het toevoegen / bewerken / verwijderen / itereren van en door de verschillende PUI's verzorgt.

Voordeel van de aanpak om je code voor validatie en conversie in de PUI-klasse te zetten en de code voor het toevoegen, sorteren enzovoorts in de overkoepelende PUI's-klasse (hoe heet dat principe?) is dat je die code herbruikbaar op de juiste plek hebt staan in plaats van allemaal in een loopje.

[ Voor 3% gewijzigd door CodeCaster op 04-01-2010 17:11 ]

https://oneerlijkewoz.nl
Op papier is hij aan het tekenen, maar in de praktijk...


Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 16-09 09:15

Janoz

Moderator Devschuur®

!litemod

Dat is inderdaad een groot voordeel, maar wat ik persoonlijk zelf als groter voordeel ervaar is dat je minder afhankelijk bent van tikfoutjes. Bij al die maps (want dat zijn het eigenlijk) hoef je maar 1 keer ergens een key verkeert getikt te hebben en je bent uren aan het debuggen. Bij een class krijg je (als het goed is) gewoon een syntax error.

En als je ook nog eens gebruik maakt van een fatsoenlijke IDE dan heb je ook nog eens code completion voor je properties

[ Voor 15% gewijzigd door Janoz op 04-01-2010 17:22 ]

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • PeetR
  • Registratie: Februari 2002
  • Laatst online: 13-09 22:20
@CodeCaster & Janoz
Dit hele principe staat mij wel aan eigenlijk, maar hoe ik het concreet in de praktijk moet brengen ben ik nog niet helemaal over uit.

@NMe
Ik begrijp wel ongeveer wat er gebeurd in de code. Heb het op deze manier nog nooit gezien. Ik zie constucties die ik niet helemaal begrijp bijv:
PHP:
1
$datalinesHelp[$dataline['code']]['text']  = $dataline['text'];

Ik neem aan de $datalinesHelp een hulp-array is, maar de plaatsing van de blokhaken snap ik niet helemaal.

ps @Janoz
Ik gebruik UltraEdit als editor. Heb daarin nog geen code-completion gevonden, maar het zoekt iig de accolades bij elkaar ;)

[ Voor 12% gewijzigd door PeetR op 04-01-2010 17:46 ]

Your time as a student is the best time of your life


Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

PeetR schreef op maandag 04 januari 2010 @ 17:45:
Ik begrijp wel ongeveer wat er gebeurd in de code. Heb het op deze manier nog nooit gezien. Ik zie constucties die ik niet helemaal begrijp bijv:
PHP:
1
$datalinesHelp[$dataline['code']]['text']  = $dataline['text'];

Ik neem aan de $datalinesHelp een hulp-array is, maar de plaatsing van de blokhaken snap ik niet helemaal.
$array['index'] betekent niet meer dan dat je van het array genaamd $array de waarde wil hebben die geassociëerd is aan de index 'index'. Je krijgt daar dus gewoon een waarde uit; laten we voor dit voorbeeld zeggen dat er 'value' in staat als string. Die waarde kun je weer gewoon (bijna) overal in gebruiken waar je normaal een string in zou stoppen. In dit geval zou dit: $datalinesHelp[$array['index']]['text'] = $dataline['text']; hetzelfde zijn als dit: $datalinesHelp['value']['text'] = $dataline['text'];
;)

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • Shagura
  • Registratie: Augustus 2001
  • Laatst online: 14-09 08:25
PeetR schreef op maandag 04 januari 2010 @ 17:45:
@NMe
Ik begrijp wel ongeveer wat er gebeurd in de code. Heb het op deze manier nog nooit gezien. Ik zie constucties die ik niet helemaal begrijp bijv:
PHP:
1
$datalinesHelp[$dataline['code']]['text']  = $dataline['text'];

Ik neem aan de $datalinesHelp een hulp-array is, maar de plaatsing van de blokhaken snap ik niet helemaal.
Misschien was het was leesbaarder geweest als ik die code in een key var had gestopt :P
PHP:
1
2
$key = $dataline['code'];
$datalinesHelp[$key]['text'] = $dataline['text'];

DatalinesHelp[$key] is dus een hulparray die geindexeerd is op de 'code' waarden van de datalines. Dit is zelf echter ook weer een array en vandaar het 2e paar blokhaken.

Dit is zo gedaan omdat je bij elke iteratie wilt kijken of de code al bestond en dat gaat op de key van een array lekker snel (constante tijd). Het zou bijvoorbeeld ook met een array_search kunnen, waar hij alle waarden af moet lopen tot hij deze vindt, maar dat is dus een stuk langzamer (lineaire tijd).

Zo krijg je dus uiteindelijk na de 1e foreach loop een array die er zo uitziet:
PHP:
1
2
3
4
5
6
7
8
9
10
$datalinesHelp = array( 
    123456 => array( 
        'text' => 'tekst', 
        'bla' => array('blatekst', 'andereblatekst') 
    ), 
    124300 => array( 
        'text' => 'tekst', 
        'bla' => array('blatekst') 
    ) 
);

Deze array bevat alle informatie die je wil, de 2e foreach loop giet deze alleen in de vorm die jij wilde hebben nav. de startpost.

Verder is alles lekker abstraheren met objecten en klassen wel mooi(er) natuurlijk, maar ik ben bang om hier een voorbeeld te geven van object composities als je deze array syntax al niet begrijpt ;) (nofi)
CodeCaster schreef op maandag 04 januari 2010 @ 17:06:
Voordeel van de aanpak om je code voor validatie en conversie in de PUI-klasse te zetten en de code voor het toevoegen, sorteren enzovoorts in de overkoepelende PUI's-klasse (hoe heet dat principe?) is dat je die code herbruikbaar op de juiste plek hebt staan in plaats van allemaal in een loopje.
Composition bedoel je denk ik.

Acties:
  • 0 Henk 'm!

  • PeetR
  • Registratie: Februari 2002
  • Laatst online: 13-09 22:20
Ik had nog niet heel diep naar de syntax gekeken, als ik eens naar de output van $datalinesHelp had gekeken, dan had ik het wel gesnapt. Eigenlijk heel logisch allemaal.

Ben toch wel benieuwd naar een oplossing aan de hand van objecten en klassen. Wees niet bang dat ik het niet zal snappen, heb al hele lappen geschreven met klassen, maar ze misschien nog niet op de juiste manier gebruikt?
(sterker nog, dit probleempje maakte onderdeel uit van een functie in een class.)

Your time as a student is the best time of your life


Acties:
  • 0 Henk 'm!

  • pedorus
  • Registratie: Januari 2008
  • Niet online
Ach, we zijn toch sinterklaas in dit draadje:
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
class Dataline {
    public $code;
    public $text;
    public $bla;

    public function __construct($code, $text, $bla) {
        $this->code = $code;
        $this->text = $text;
        $this->bla = $bla;
    }

    public function absorb($other) {
        if (!is_array($this->bla))
            $this->bla = array($this->bla);
        $this->bla[] = $other->bla;
    }
}

$datalines = array(
    new Dataline(123456, 'tekst', 'blatekst'),
    new Dataline(123456, 'tekst', 'andereblatekst'),
    new Dataline(124300, 'tekst', 'blatekst')
); //for example returned by PDOStatement::fetchAll

foreach($datalines as $dataline) {
    $place = &$newDatalines[$dataline->code];
    if (is_null($place))
        $place = clone $dataline;
    else
        $place->absorb($dataline);
}
unset($place);
$newDatalines = array_values($newDatalines);

var_export($datalines);
var_export($newDatalines);

clone hoort eigenlijk groen te zijn, en is alleen nodig als je de oude objecten nog wil gebruiken. Overigens is het wel gek dat $bla zowel een string als een array kan zijn... ;)

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten

Pagina: 1