Gå til innhold

[Løst]Rekursiv funksjon vil ikke returnere verdier


Anbefalte innlegg

Jeg sitter her med en funksjon som skal brukes med Wordpress. Tanken er at den skal finne alle foreldrene/besteforeldrene til en post, putte dem i et array, og returnere arrayet når den har kommet til toppen (parent == 0) (Jeg har fjernet irrelevant kode for lesbarhetens skyld.)

function get_parents($post_id, $arr = array()){
$parent = //resultatet av en spørring som fungerer
if($parent == 0){
	return $arr;
} else {
	$arr[] = $parent;
	get_parents($parent, $arr);
}
}

Dersom jeg gjør print_r($arr); rett over return $arr får jeg ut riktige verdier, men når jeg kaller funksjonen med $parents = get_parents($post->ID); i et annet script, får jeg bare null tilbake.

 

Er det noen som ser hva som er galt?

Endret av G2Petter
Lenke til kommentar
Videoannonse
Annonse

Jeg blir alltid litt rotete i hodet av rekursive kall, men jeg prøver å se for meg hvordan dette funker.

 

La oss si du har 2 nivå over der du er:

 

1. Du kaller først metoden din, den retunerer at det finnes en forelder og du kaller metoden en gang til

 

2. Dette kallet finner en forelder (besteforelder til første kallet) og kaller metoden en gang til

 

3. Dette kallet finner 0, ettersom det ikke finnes olderforelder (slik jeg skjønner) og returnerer det ett nivå ned.

 

Men så kommer cluet:

 

Du er nå tilbake til linje 2 i beskrivelsen min. Men ser du i denne metoden, så langt som du har kommet i den, har du ingen return av $arr tilbake til "linje 1"/første kall.

Og det samme i "linje 1", du har ingen return av $arr der heller.

 

Prøv å legge inn return $arr etter if'en.

 

 

EDIT: Jeg blir litt forvirret over at du har $arr=$array() i første linje. Vil ikke dette hver gang opprette en ny (blank) array?

(jeg har ikke mulighet til å teste selv)

Endret av Ekko
Lenke til kommentar

Ikke sikker på ka du egentlig er ute etter med array og den spørringen.

 

Ser ut som noe du egentlig kan loope over med noe slikt.

function get_parents($post_id) {
$arr = array();
while (0 !== $parent = "spørring som fungerer") {
	$arr[] = $parent;
}
return $arr;
}

 

Ellers kan du kanskje enten bruke noe slikt

function get_parents($post_id, $arr = array()){
$parent = //resultatet av en spørring som fungerer
if($parent !== 0){
	$arr[] = $parent;
	get_parents($parent, &$arr);
}
return $arr;
}

eller noe slikt

function get_parents($post_id){
$parent = //resultatet av en spørring som fungerer
if($parent == 0){
	$arr = array();
} else {
	$arr = get_parents($parent);
	$arr[] = $parent;
}
return $arr;
}

Endret av OIS
Lenke til kommentar
Jeg blir alltid litt rotete i hodet av rekursive kall, men jeg prøver å se for meg hvordan dette funker.

 

La oss si du har 2 nivå over der du er:

 

1. Du kaller først metoden din, den retunerer at det finnes en forelder og du kaller metoden en gang til

 

2. Dette kallet finner en forelder (besteforelder til første kallet) og kaller metoden en gang til

 

3. Dette kallet finner 0, ettersom det ikke finnes olderforelder (slik jeg skjønner) og returnerer det ett nivå ned.

 

Men så kommer cluet:

 

Du er nå tilbake til linje 2 i beskrivelsen min. Men ser du i denne metoden, så langt som du har kommet i den, har du ingen return av $arr tilbake til "linje 1"/første kall.

Og det samme i "linje 1", du har ingen return av $arr der heller.

 

Prøv å legge inn return $arr etter if'en.

 

Det kan hende du er inne på noe der: at den bare returnerer til funksjonen som kaller den, og ikke det eksterne kallet. Det kan gi mening. Jeg skal teste det litt nå.

 

EDIT: Jeg blir litt forvirret over at du har $arr=$array() i første linje. Vil ikke dette hver gang opprette en ny (blank) array?

(jeg har ikke mulighet til å teste selv)

Det er en default-verdi. Dersom funksjonen kalles med kun ett argument oppretter den et tomt array, men det blir overskrevet dersom jeg gir det andre argumentet.

Ikke sikker på ka du egentlig er ute etter med array og den spørringen.

 

Ser ut som noe du egentlig kan loope over med noe slikt.

function get_parents($post_id) {
$arr = array();
while (0 !== $parent = "spørring som fungerer") {
	$arr[] = $parent;
}
return $arr;
}

Jeg kan ikke helt se hvordan det skal fungere; grunnen til det rekursive kallet er at jeg vil finne foreldre og besteforeldre til utgangsposten helt til det ikke er noen. Om det er 1 eller 5 skal ikke ha noe å si.

Ellers kan du kanskje enten bruke noe slikt

function get_parents($post_id, $arr = array()){
$parent = //resultatet av en spørring som fungerer
if($parent !== 0){
	$arr[] = $parent;
	get_parents($parent, &$arr);
}
return $arr;
}

Det fungerer ikke, det returnerer bare verdien funksjonen har etter første kjøring.

eller noe slikt

function get_parents($post_id){
$parent = //resultatet av en spørring som fungerer
if($parent == 0){
	$arr = array();
} else {
	$arr = get_parents($parent);
	$arr[] = $parent;
}
return $arr;
}

Det vil i hvert fall ikke fungere, fordi det overskriver det genererte arrayet når du endelig har kommet til toppen.

 

Takk for hjelp så langt til begge to. Jeg skal kikke på noen ideer jeg har fått nå.

Lenke til kommentar

Følgende fungerte:

function get_parents($post_id, $arr = array()){
$parent = //resultatet av en spørring som fungerer
if($parent == 0){
	return $arr;
} else {
	$arr[] = $parent;
	$arr = get_parents($parent, $arr);
	return $arr
}
}

 

Takk til Ekko for å ha ført meg i riktig retning.

Lenke til kommentar

Hadde en feil i loopen i mitt første eksempel. Har testet alle 4 løsningene med en "enkel spørring" og alle fikk circa samme resultat. I mitt eksempel 3 var slutt resultatet reversert i forhold til de andre eksemplene, men riktig i forhold til utgangspunktet.

 

Kode:

 

$data = array(
5 => 4,
4 => 3,
3 => 2,
2 => 1,
1 => 0,
);

/* OIS 1 - OK - reverse
function get_parents($parent) {
$arr = array();
while (0 !== $parent = $GLOBALS['data'][$parent]) {
	$arr[] = $parent;
}
return $arr;
}
//*/
/* OIS 2 - OK - reverse
function get_parents($post_id, $arr = array()){
$parent = $GLOBALS['data'][$post_id];
if($parent !== 0){
	$arr[] = $parent;
	get_parents($parent, &$arr);
}
return $arr;
}
//*/
/* OIS 3 - OK
function get_parents($post_id){
$parent = $GLOBALS['data'][$post_id];
if($parent == 0){
	$arr = array();
} else {
	$arr = get_parents($parent);
	$arr[] = $parent;
}
return $arr;
}
//*/
/* G2Petter - OK - reverse
function get_parents($post_id, $arr = array()) {
$parent = $GLOBALS['data'][$post_id];
if($parent == 0) {
	return $arr;
} else {
	$arr[] = $parent;
	$arr = get_parents($parent, $arr);
	return $arr;
}
}
//*/

var_dump(get_parents(5));

 

 

Resultat:

 

 

Resultat OIS1, 2 og G2Petter:

array(4) {
 [0]=>
 int(4)
 [1]=>
 int(3)
 [2]=>
 int(2)
 [3]=>
 int(1)
}

Resultat OIS 3:

array(4) {
 [0]=>
 int(1)
 [1]=>
 int(2)
 [2]=>
 int(3)
 [3]=>
 int(4)
}

 

 

 

Vil derfor forslå loopen, da den er enklere og raskere.

Lenke til kommentar

Enten er det noe jeg misforstår (mye mulig), eller så har du misforstått datastrukturen som benyttes for å lagre denne informasjonen. Forenklet ser tabellen som inneholder postinformasjon sånn ut:

posts {ID, parent (references posts.ID)}

Spørringen ser sånn ut:

SELECT post_parent
FROM posts
WHERE ID = '$post_id'
AND post_status = 'publish'
AND post_type = 'page'

Så så vidt jeg ser det må jeg enten forandre spørringen til å returnere hele datasettet, noe jeg ikke er sikker på hvordan jeg skal gjøre, eller så må jeg kjøre spørringen for hver parent.

 

Gir dette mening, eller er jeg helt på viddene?

Lenke til kommentar
Enten er det noe jeg misforstår (mye mulig), eller så har du misforstått datastrukturen som benyttes for å lagre denne informasjonen. Forenklet ser tabellen som inneholder postinformasjon sånn ut:

posts {ID, parent (references posts.ID)}

Spørringen ser sånn ut:

SELECT post_parent
FROM posts
WHERE ID = '$post_id'
AND post_status = 'publish'
AND post_type = 'page'

Så så vidt jeg ser det må jeg enten forandre spørringen til å returnere hele datasettet, noe jeg ikke er sikker på hvordan jeg skal gjøre, eller så må jeg kjøre spørringen for hver parent.

 

Gir dette mening, eller er jeg helt på viddene?

 

Loopen er lik om du har all data cachet eller om du henter en og en.

 

Dette kan kanskje hjelpe deg med å skrive koden i mysql:

http://dev.mysql.com/tech-resources/articl...hical-data.html

http://www.sitepoint.com/article/hierarchical-data-database/

Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
×
×
  • Opprett ny...