Antwort zuordnen in einer Liste - Schleifenproblem

Fragen zu allen Themen rund ums Programmieren außerhalb von phpBB können hier gestellt werden - auch zu anderen Programmiersprachen oder Software wie Webservern und Editoren.
Antworten
Benutzeravatar
mgutt
Mitglied
Beiträge: 2999
Registriert: 31.08.2004 16:44
Wohnort: Hennef
Kontaktdaten:

Antwort zuordnen in einer Liste - Schleifenproblem

Beitrag von mgutt »

Folgende Daten habe ich:

00. 24
01. 21
02. 19
03. 18
04. 13
05. 12
06. 8
07. 5
08. 4
09. 3
10. 2
11. 1
12. 0
13. 1
14. 0
15. 2
16. 1
17. 0
18. 3
19. 2
20. 1
21. 0
22. 0
23. 1
24. 0

Ich habe die Daten damit aufs Nötigste reduziert. Die erste Zahl ist die Zeilennummer und die 2. Zahl die Anzahl der zugehörigen Unterzeilen.

D.h.:
- der Zeile 00 folgen 24 Zeilen (01-24)
- der Zeile 06 folgen 8 Zeilen (07-12 und 13-14)
- der Zeile 18 folgen 3 Zeilen (19-21)

Das Prinzip ist erkennbar. Nun muss ich aber genau dieses Prinzip mit einer Schleife umsetzen. Und zwar muss ich jeder Zeile Ihren Master zuordnen.

D.h.:
- 00 hat keine
- 01 hat 00 als Master
- 02 hat 01 als Master
- 03 hat 02 als Master
- 04 hat 03 als Master
- 05 hat 04 als Master
- 06 hat 05 als Master
usw.
- 22 hat 01 als Master
- 23 hat 00 als Master
- 24 hat 23 als Master

Jetzt frage ich mich, wie ich das automatisiert hinkriegen könnte.

Im Kopf mache ich das, in dem ich die Anzahl der Unterzeilen nehme, abzähle und dann weiß, dass alle die dann danach kommen eine neue Gruppe bilden.

Aber gerade wenn es so verschachtelt ist wie jetzt, ist das beim nachdenken teilweise so unübersichtlich, dass ich es mir gerade selber schwer mache, daraus eine automatische Schleife zu basteln.

Bedingungen, die ich jetzt schon klar weiß:
- 00 muss ein Master sein, da vor ihr keine Zeile mehr kommt
- 01 muss 00 als Master haben, da sonst kein Master in Frage kommt
;)

- 02 hat selbst 19 Unterzeilen, da die möglichen Antworten aus Zeile 01 nicht aufgebraucht sind, muss die Zeile 01 auch die Masterzeile sein.
...
Da muss schon der Denkfehler sein. Denn wenn ich X verschachtelte Elemente aufbaue, müsste ich bei jeder Unterzeilengruppe einen Zähler mitlaufen lassen. Und da ich die Schachteltiefe nicht kenne (auch nicht die Maximale) wüsste ich nicht, wie ich da klar kommen soll.

Hier vielleicht noch mal ein Skizze. Beim Anfertigen ist mir aufgefallen, dass ich von Innen nach Außen gearbeitet habe. Anders ist es denke ich vielleicht gar nicht machbar :-?

[ externes Bild ]
meine Foren: http://www.maxrev.de/communities.htm
Ich kaufe Dein Forum! Angebote bitte an marc at gutt punkt it
Benutzeravatar
Banger
Ehemaliges Teammitglied
Beiträge: 375
Registriert: 03.05.2005 21:53
Wohnort: Düsseldorf
Kontaktdaten:

Beitrag von Banger »

Servus,

hiermit bekommst Du zu jeder Zeile ein Array mit den dazugehörigen Master, hierarchisch aufsteigend:

Code: Alles auswählen

<?php
$lines = array(
	'00' => 24,
	'01' => 21,
	'02' => 19,
	'03' => 18,
	'04' => 13,
	'05' => 12,
	'06' => 8,
	'07' => 5,
	'08' => 4,
	'09' => 3,
	'10' => 2,
	'11' => 1,
	'12' => 0,
	'13' => 1,
	'14' => 0,
	'15' => 2,
	'16' => 1,
	'17' => 0,
	'18' => 3,
	'19' => 2,
	'20' => 1,
	'21' => 0,
	'22' => 0,
	'23' => 1,
	'24' => 0, 
);
$keys = array_keys($lines);
$masters = array();
foreach($keys as $k) 
    $masters[$k] = array(); #init
    
while($keys) {
    $k = array_shift($keys);
    foreach(array_slice($keys, 0, $lines[$k]) as $p)
        array_unshift($masters[$p], $k);
}
?>
Das ergibt dann beispielsweise für Zeile 14 folgende Masterzeilen:

Code: Alles auswählen

    [14] => Array
        (
            [0] => 13
            [1] => 06
            [2] => 05
            [3] => 04
            [4] => 03
            [5] => 02
            [6] => 01
            [7] => 00
        )
Falls Du nur das direkte Elternelement brauchst, kannst Du den Code auch so abwandeln und daraus die Struktur ermitteln:

Code: Alles auswählen

$masters = array();
    
while($keys) {
    $k = array_shift($keys);
    foreach(array_slice($keys, 0, $lines[$k]) as $p)
        $masters[$p] = $k;
}

function get_children($master, &$masters) {
    return array_keys($masters, $master);
}
function get_nested($master, &$masters) {
    $ret = array();
    foreach(get_children($master, $masters) as $k)
        $ret[$k] = get_nested($k, $masters);
    return $ret; 
}
    
#Kindelemente einzeln suchen, exemplarisch für Zeile '00':
$children_00 = get_children('00', $masters);

#komplette Struktur abbilden:
$struct = array('00' => get_nested('00', $masters)); 
Benutzeravatar
mgutt
Mitglied
Beiträge: 2999
Registriert: 31.08.2004 16:44
Wohnort: Hennef
Kontaktdaten:

Beitrag von mgutt »

Richtig verstanden habe ich es zwar nicht, aber Du hast mir in jedem Fall geholfen. Ich brauche nur den ersten Master, daher habe ich mir das so angepasst:

Code: Alles auswählen

<?php 
$lines = array(
   '00' => 24,
   '01' => 21,
   '02' => 19,
   '03' => 18, 
   '04' => 13,
   '05' => 12,
   '06' => 8,
   '07' => 5,
   '08' => 4, 
   '09' => 3, 
   '10' => 2,
   '11' => 1, 
   '12' => 0, 
   '13' => 1,
   '14' => 0, 
   '15' => 2, 
   '16' => 1, 
   '17' => 0, 
   '18' => 3,
   '19' => 2,
   '20' => 1,
   '21' => 0,
   '22' => 0,
   '23' => 1,
   '24' => 0,
);
$keys = array_keys($lines);
$masters = array();
/*
foreach($keys as $k)
{
	$masters[$k] = array(); #init
}
while($keys)
{
    $k = array_shift($keys);
    foreach(array_slice($keys, 0, $lines[$k]) as $p)
	{
		array_unshift($masters[$p], $k);
	}
}
*/
while($keys)
{
    $k = array_shift($keys);
    foreach(array_slice($keys, 0, $lines[$k]) as $p)
	{
		$masters[$p] = $k;
	}
}
echo('<pre>');
print_r($masters);
echo('</pre>');
?>
Ich steig nicht durch die array_shift / array_slice Kombination.
meine Foren: http://www.maxrev.de/communities.htm
Ich kaufe Dein Forum! Angebote bitte an marc at gutt punkt it
Benutzeravatar
Banger
Ehemaliges Teammitglied
Beiträge: 375
Registriert: 03.05.2005 21:53
Wohnort: Düsseldorf
Kontaktdaten:

Beitrag von Banger »

mgutt hat geschrieben:Ich steig nicht durch die array_shift / array_slice Kombination.
Nun, das ist eigentlich ganz einfach: mit dem array_shift wird das $keys-Array jeweils um ein Element abgeschnitten - das noch bestehende Array repräsentiert die möglichen Kindelemente, von denen die tatsächlichen Anzahl der Kindelemente per array_slice() geholt wird.
Schau Dir am besten mal die PHP-Doku dazu an - array_slice() funktioniert bei Arrays vergleichbar mit substr() bei Strings.
Benutzeravatar
mgutt
Mitglied
Beiträge: 2999
Registriert: 31.08.2004 16:44
Wohnort: Hennef
Kontaktdaten:

Beitrag von mgutt »

Sorry, falsch formuliert.

Ich weiß schon was die beiden machen, aber ich weiß nicht, wie es die Schleife dabei schafft, die Hierarchy zu erstellen.

Beim ersten Aufruf von array_shift übergibt er das erste Element des $key arrays an $k, also "00". Danach bleibt in $keys nur noch "01-24" übrig. Dann reduziert array_slice $keys erneut vom ersten bis zum letzten Wert. Also bleibt immernoch "01-24", da $k ja in dem Fall "00" ist. Das was übrig bleibt aus array_slice, also "01-24" wandert dann nach und nach per foreach in $p (beim ersten Wert also "01"). $p ist der Indexwert für das neue Array und wird mit $k also "00" gefüllt.

D.h. jedes Element bis auf "00" hat "00" als Master. Beim nächsten Durchlauf fällt "01" raus. Also behält "01" als Master "00". usw.

Soweit bin ich dem ganzen schon auf der Spur. Doch was passiert bei "13"? Wie kommt es am Ende zu der "06"?

Gruß
meine Foren: http://www.maxrev.de/communities.htm
Ich kaufe Dein Forum! Angebote bitte an marc at gutt punkt it
Benutzeravatar
Banger
Ehemaliges Teammitglied
Beiträge: 375
Registriert: 03.05.2005 21:53
Wohnort: Düsseldorf
Kontaktdaten:

Beitrag von Banger »

mgutt hat geschrieben:Doch was passiert bei "13"? Wie kommt es am Ende zu der "06"?
Das sieht man doch ganz einfach anhand Deiner Zeichnung:
Zeile 06 hat 8 Kindelemente - also die Zeilen 07-14. Da Zeile 13 ansonsten keine Elternzeilen hat, bleibt nur die 06 übrig.
Antworten

Zurück zu „Coding & Technik“