Seite 1 von 1

Antwort zuordnen in einer Liste - Schleifenproblem

Verfasst: 31.01.2007 21:12
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 ]

Verfasst: 01.02.2007 13:26
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)); 

Verfasst: 01.02.2007 15:06
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.

Verfasst: 01.02.2007 15:18
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.

Verfasst: 01.02.2007 15:39
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ß

Verfasst: 01.02.2007 16:14
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.