[PHP] Array's optellen

Pagina: 1
Acties:
  • 671 views sinds 30-01-2008
  • Reageer

Onderwerpen


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Ik probeer een functie te schrijven die de eerste, tweede, derde, etc. elementen van een x aantal arrays optelt en in een nieuwe array zet:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$arr = array(
  array(3, 5, 7, 9),
  array(2, 4, 6, 8),
  array(1, 3, 5, 7)
);

function add_arrays($arr) {
  for ($i = 0; $i < count($arr); $i++) {
    for ($j = 0; $j < count($arr[$i]); $j++) {
      $totals[$i] = $totals[$i] + $arr[$i][$j];
    }
  }
  print_r($totals);
}

add_arrays($arr);

Deze code geeft als resultaat
code:
1
2
3
4
5
Array (
    [0] => 24 // 3 + 5 + 7 + 9
    [1] => 20 // 2 + 4 + 6 + 8
    [2] => 16 // 1 + 3 + 5 + 7
)

Maar ik verwachtte
code:
1
2
3
4
5
6
Array (
    [0] => 6  // 3 + 2 + 1
    [1] => 12 // 5 + 3 + 3
    [2] => 18 // 7 + 6 + 5
    [3] => 34 // 9 + 8 + 7
)

Ik zie wat er verkeerd gaat: hij telt de inhoud van elke array bij elkaar op ipv de eerste elementen van alle array's etc. Ik snap alleen niet hoe mijn loop anders moet. Ik raak erg in de war van alle $i's en $j's ;) Graag jullie hulp!

Acties:
  • 0 Henk 'm!

  • 2playgames
  • Registratie: Februari 2005
  • Laatst online: 01-06 15:19
je hebt nu een herhaling die door de hoofdarray loopt, met daarin een herhaling die door een subarray loopt. dat moet dus andersom :)

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
2playgames schreef op zondag 06 mei 2007 @ 22:10:
je hebt nu een herhaling die door de hoofdarray loopt, met daarin een herhaling die door een subarray loopt. dat moet dus andersom :)
Graag pseudo of codevoorbeeld, want ik snap niet hoe :? Ik wordt er gek van ... mijn gedachten gaan maar in een kringetje :|

[ Voor 10% gewijzigd door Verwijderd op 06-05-2007 22:24 ]


Acties:
  • 0 Henk 'm!

  • dEUSdude
  • Registratie: Juni 2002
  • Niet online
PHP:
1
2
3
4
5
6
7
8
function add_arrays($arr) { 
  for ($i = 0; $i < count($arr); $i++) { 
    for ($j = 0; $j < count($arr[$i]); $j++) { 
      $totals[$i] = $totals[$i] + $arr[$j][$i]; 
    } 
  } 
  print_r($totals); 
}


geeft:

code:
1
2
3
4
5
6
Array
(
    [0] => 6
    [1] => 12
    [2] => 18
)


Je zat er dichtbij...
Met dank aan 2playgames voor de voorzet.

[ Voor 6% gewijzigd door dEUSdude op 06-05-2007 22:27 . Reden: Credits toevoegen ]


Acties:
  • 0 Henk 'm!

Verwijderd

Daarom is het ook belangrijk duidelijke variablen te gebruiken.

De tijd dat we maar 1 letter beschikbaar hadden voor een variabele is al ver achter ons, gebruik dus gewoon goed lange leesbare variabelen, dat voorkomt vaak dit soort problemen.

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
dEUSdude schreef op zondag 06 mei 2007 @ 22:25:
code:
1
2
3
4
5
6
Array
(
    [0] => 6
    [1] => 12
    [2] => 18
)


Je zat er dichtbij...
Met dank aan 2playgames voor de voorzet.
Dan ontbreekt er dus nog 1
code:
1
2
3
4
5
6
7
Array
(
    [0] => 6
    [1] => 12
    [2] => 18
    [3] => 24
)

Dat komt omdat de $i loop maar 3 keer gemaakt wordt ($i = 0, 1 en 2) en niet 4 keer (elke sub-array heeft 4 elementen). Ziehier de verwarring :) Iemand?

Acties:
  • 0 Henk 'm!

  • dEUSdude
  • Registratie: Juni 2002
  • Niet online
PHP:
1
2
3
4
5
6
7
8
function add_arrays($arr) {
  for ($rij = 0; $rij < count($arr[0]); $rij++) {
    for ($kolom = 0; $kolom < count($arr[$kolom]); $kolom++) {
      $totals[$rij] = $totals[$rij] + $arr[$kolom][$rij]; 
    } 
  } 
  print_r($totals); 
}


Dan moet dit het wel doen, met verandering van line 3:

PHP:
1
    for ($kolom = 0; $kolom < count($arr[$kolom]); $kolom++) {


Ik krijg nu:

code:
1
2
3
4
5
6
7
Array
(
    [0] => 6
    [1] => 12
    [2] => 18
    [3] => 24
)

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Dank je, dEUSdude! Ik snap nog niet precies hoe het werkt, maar daar ga ik morgenochtend maar eens even op zitten :)

[edit]

PHP:
1
2
3
4
5
6
7
8
function add_arrays($arr) {
  for ($rij = 0; $rij < count($arr[0]); $rij++) {
    for ($kolom = 0; $kolom < count($arr[$kolom]); $kolom++) {
      $totals[$rij] = $totals[$rij] + $arr[$kolom][$rij]; 
    } 
  } 
  print_r($totals); 
}

Ik ben er het afgelopen uur mee aan het spelen geweest, maar ik snap het niet helemaal. Als ik deze code lees, had ik verwacht dat de uitkomst een aantal array's zou zijn, zoals:
code:
1
2
3
4
5
Array (
  Array ( [0] => 3 [1] =>  5 [2] =>  7 [3] =>  9 ) // rij 1
  Array ( [0] => 5 [1] =>  9 [2] => 13 [3] => 17 ) // rij 1 + rij 2
  Array ( [0] => 6 [1] => 12 [2] => 18 [3] => 24 ) // rij 1 + rij 2 + rij 3
)

Met andere woorden: de output is een multidimensionale array met een array voor elke rij. Rijen worden opgeteld, en voor elke keer dat we door de loop gaan wordt er een extra rij opgeteld. Toch is de uitkomst zo:
code:
1
Array ( [0] => 3 [1] => 5 [2] => 7 [3] =>  9 )

Ik probeer erachter te komen welke loop dan de multidimensionale array als output zou geven. Als ik regel 4 verander in
PHP:
1
$totals[$rij] = $totals[$rij] + $arr[$kolom - 1][$rij];
krijg ik de volgende output:
code:
1
Array ( [0] => 5 [1] => 9 [2] => 13 [3] => 17 )

Dit is het resultaat van de 1e + 2e rij. Maar de 1e rij ende 1e, 2e en 3e opgeteld ontbreken. Wie kan mij laten zien hoe dat zou moeten?

[ Voor 85% gewijzigd door Verwijderd op 07-05-2007 01:01 ]


Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 02:21

Janoz

Moderator Devschuur®

!litemod

Als je in je orginele code uit de startpost beide $total[$i] 's vervangt door $total[$j] 's dan was je er ook al geweest ;)

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!

Verwijderd

@plaksel,

Je gebruikt:

PHP:
1
$totals[$rij] = ...


Aangezien $rij in de code de waardes 0 t/m count($arr[0]) (dus 4), krijg je dus een array met 4 key's, in jouw geval 1 voor elke rij. Je situatie die jij verwacht is een meer-dimensionale array en zou je krijgen indien je deed: $totals[$rij][]. Misschien dat dit het wat duidelijker maakt. De optelling die je doet is eigenlijk x = x +y, je verhoogt de huidige array_waarde met de corresponderende waarde uit de begin array. Wat voor mij altijd goed werkt om dit soort problemen te tackelen, is gewoon proberen (desnoods met pen/papier) om de procedure zelf te doorlopen.

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
@Bo-oz - het is me duidelijk dat ik, om meerdere array's te krijgen, [] moet gebruiken (zie regel 4):
PHP:
1
2
3
4
5
6
7
8
function add_arrays($arr) {
  for ($rij = 0; $rij < count($arr[0]); $rij++) {
    for ($kolom = 0; $kolom < count($arr[$kolom]); $kolom++) {
      $totals[$rij][] = $totals[$rij] + $arr[$kolom][$rij];
    } 
  } 
  print_r($totals);
}

Ik krijg dan alleen een foutmelding:
Fatal error: Unsupported operand types in C:\Program Files\\Apache2\htdocs\test\array-optellen.php on line 4
Ik snap niet waarom ik die foutmelding krijg. [] is toch een legitieme operatie?

Acties:
  • 0 Henk 'm!

  • stp_4
  • Registratie: Maart 2003
  • Laatst online: 17-09 20:25
Je moet denk ik wel een index opgeven.

stp - PSN ID: stp_4


Acties:
  • 0 Henk 'm!

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
Index hoeft niet opgegeven te worden. De operator waar het fout gaat is namelijk de '+'. $totals[$rij] is nu een array en bevat geen numerieke waarde. Je probeert dus een waarde bij een array op te tellen.

{signature}


Acties:
  • 0 Henk 'm!

  • stp_4
  • Registratie: Maart 2003
  • Laatst online: 17-09 20:25
Voutloos schreef op maandag 07 mei 2007 @ 13:04:
Index hoeft niet opgegeven te worden. De operator waar het fout gaat is namelijk de '+'. $totals[$rij] is nu een array en bevat geen numerieke waarde. Je probeert dus een waarde bij een array op te tellen.
Inderdaad, nu zie ik het ook....

stp - PSN ID: stp_4


Acties:
  • 0 Henk 'm!

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
Maar je wil toch alleen een array met de totalen? Het antwoord is toch al gegeven dan? Wat dan belangrijk is, is dat je begrijpt wat er gebeurt en volgens mij interpreteer je de volgende regel verkeerd:
dEUSdude schreef op zondag 06 mei 2007 @ 22:59:
PHP:
4
      $totals[$rij] = $totals[$rij] + $arr[$kolom][$rij];
Hier staat: Het element in de totals array met key $rij wordt de oude waarde van dit element + de waarde van $arr[$kolom][$rij].

Overigens moet de eindconditie van de for loop over de rijen $rij < count($arr) zijn ipv $rij < count($arr[0]), maar verder snap ik niet waarom de post van dEUSdude nog niet 'de' oplossing bevat.

{signature}


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Voutloos schreef op maandag 07 mei 2007 @ 13:18:
[...]
Overigens moet de eindconditie van de for loop over de rijen $rij < count($arr) zijn ipv $rij < count($arr[0]), maar verder snap ik niet waarom de post van dEUSdude nog niet 'de' oplossing bevat.
Die bevat wel de oplossing, en daar ben ik ook erg blij mee. Maar:
Verwijderd schreef op zondag 06 mei 2007 @ 23:38:
Dank je, dEUSdude! [...]
Ik ben er het afgelopen uur mee aan het spelen geweest, maar ik snap het niet helemaal. Als ik jouw code lees, had ik verwacht dat de uitkomst een aantal array's zou zijn, zoals:
code:
1
2
3
4
5
Array (
  Array ( [0] => 3 [1] =>  5 [2] =>  7 [3] =>  9 ) // rij 1
  Array ( [0] => 5 [1] =>  9 [2] => 13 [3] => 17 ) // rij 1 + rij 2
  Array ( [0] => 6 [1] => 12 [2] => 18 [3] => 24 ) // rij 1 + rij 2 + rij 3
)

Met andere woorden: de output is een multidimensionale array met een array voor elke rij. Rijen worden opgeteld, en voor elke keer dat we door de loop gaan wordt er een extra rij opgeteld. Toch is de uitkomst zo:
code:
1
Array ( [0] => 3 [1] => 5 [2] => 7 [3] =>  9 )

Ik probeer erachter te komen welke loop dan de multidimensionale array als output zou geven.
Ik zou dus heel graag zien hoe ik die multi-dimensionale array als output zou kunnen krijgen, zodat ik het verschil in code kan vergelijken :)

[ Voor 10% gewijzigd door Verwijderd op 07-05-2007 13:29 ]


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Na een hoop gepruts:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$arr = array(
  array(3, 5, 7, 9),
  array(2, 4, 6, 8),
  array(1, 3, 5, 7)
);

function add_arrays($arr) {
  for ($rij = 0; $rij < count($arr[0]); $rij++) {
    for ($kolom = 0; $kolom < count($arr[$kolom]); $kolom++) {
      $subtotaal[$rij] = $subtotaal[$rij] + $arr[$kolom][$rij];
    } 
    $totals[$rij] = $subtotaal;
  } 
  print_r($totals);
}

add_arrays($arr);

Dit levert de volgende array op:
code:
1
2
3
4
5
6
Array (
  [0] => Array ( [0] => 6 )
  [1] => Array ( [0] => 6 [1] => 12 )
  [2] => Array ( [0] => 6 [1] => 12 [2] => 18 )
  [3] => Array ( [0] => 6 [1] => 12 [2] => 18 [3] => 24 )
)

Da's nog niet wat ik zoek:
code:
1
2
3
4
5
Array (
  [0] => Array ( [0] => 3 [1] =>  5 [2] =>  7 [3] =>  9 ) // rij 1
  [1] => Array ( [0] => 5 [1] =>  9 [2] => 13 [3] => 17 ) // rij 1 + rij 2
  [2] => Array ( [0] => 6 [1] => 12 [2] => 18 [3] => 24 ) // rij 1 + rij 2 + rij 3
)

Ik krijg in ieder geval een multidimensionale array terug met de totalen in de laatste array. Wie kan mij iets verder helpen?

Acties:
  • 0 Henk 'm!

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
Je hebt nu een functie welke de totalen berekent, dus wat is er nieuw? Helemaal niets.
Je wil gewoon steeds voor een rij meer blijkbaar de totalen weergeven en dat is vrij triviaal te doen met de bestaande code: Voeg een parameter toe welke het aantal rijen om op te tellen bepaalt, laat de functie de $totals array returnen en roep deze functie aan in een loopje.

Misschien niet de meest efficiënte manier, maar wel leesbaar en je gebruikt zoveel mogelijk je bestaande functie. :)

Opzetje:
PHP:
1
2
3
for($maxdepth=0; $maxdepth<count($arr); $maxdepth++) {
  $cumulative_array[$maxdepth] = add_arrays($arr, $maxdepth);
}


Als je de functie efficienter wil maken: rij N kan gewoon rij N-1 uit de totalen array zijn + de volgende rij. Dit kan wellicht in minder code dan wat je nu hebt staan, leest lekker weg als je de inductiestap begrijpt en is ook nog beter qua performance.

[ Voor 16% gewijzigd door Voutloos op 07-05-2007 16:48 ]

{signature}


Acties:
  • 0 Henk 'm!

Verwijderd

hehe. Ik heb deze opmerking nog niet gezien: array_sum

edit.
Janoz geeft het goede antwoord, door van $totals[$i] $totals[$j] te maken (zie startpost).

Plaksel veranderde $i naar $rij en $j naar $kolom.
De totals moet je uiteindelijk vullen vanuit de kolommen, niet de rijen

[ Voor 54% gewijzigd door Verwijderd op 08-05-2007 17:52 ]

Pagina: 1