Newsgroup: it.comp.www.php
Titolo: Array "profondi" :)

Salve a tutti,
è da un po' che mi ero allontanato da questo luogo di perdizione. :-)
Che si dice? Che mi sono perso?
Vabbé, ma veniamo al dunque:
ho vari array, del tipo:
$ar1 = array("stanza" => array("camera_da_letto" => array()));
$ar2 = array("abitazione" => array("stanza" => array()));
$ar3 = array("stanza" => array("salone" => array()));
$ar4 = array("abitazione" => array("accessori" => array()));
Cioè ogni array è composto da una chiave (chiamiamola in questo caso 
CLASSE) e da un altro array (composto in tal caso solo da un altro 
elemento, che chiamiamo SOTTOCLASSE).
Bene, a partire da questa rappresentazione (o magari anche da 
visualizzazioni equivalenti, se più comode da gestire, ditemi voi), 
vorrei ottenere un unico array di questo tipo:
$ar = array("abitazione" => array("stanza" => array("camera_da_letto" 
=> array(), "salone" => array())));
Cioè del tipo:
|abitazione
   |stanza
      |camera_da_letto
      |salone
   |accessori
Ovviamente le relazioni di CLASSE-SOTTOCLASSE sono molte di più, e 
quindi vorrei fare questa cosa in "automatico".
Ahimé...sarà che la vecchiaia incalza.....ma ci sto sbattendo la testa 
senza successo!
Idee?
--
rob4you

 array(), "salone" => array())));
Ops, ho sbagliato a scrivere, volevo dire:
$ar = array("abitazione" => array("stanza" => array("camera_da_letto" 
=> array(), "salone" => array()), "accessori" => array()));
--
rob4you

=> array(), "salone" => array())));
Ummm... hai gia' provato con array_merge_recursive? Se si', perche' non
vanno bene i risultati?
Leonardo
-- 
 What do you make, so fair and bright;
 What do you build with sails for flight;
 What do you weave with wool so white?

 vanno bene i risultati?
Lo avevo provato. Guarda, se io faccio qualcosa del tipo:
$ar1 = array("stanza" => array("camera_da_letto" => array()));
$ar2 = array("abitazione" => array("stanza" => array()));
$ar3 = array("stanza" => array("salone" => array()));
$ar4 = array("abitazione" => array("accessori" => array()));
$ar = array_merge_recursive($ar1,$ar2,$ar3,$ar4);
print_r($ar);
Ottengo questo:
|stanza
   |camera_da_letto
   |salone
|abitazione
   |stanza
   |accessori
Anziché quello che vorrei effettivamente:
|abitazione
   |stanza
      |camera_da_letto
      |salone
   |accessori
(nel caso specifico "stanza" è sottoclasse di "abitazione", quindi non 
dovrebbe posizionarsi allo stesso livello, ma un livello sotto).
Aiuto......se nemmeno tu ci riesci......penso che ahimé......mi 
suicido! :)
--
rob4you

 rob4you
Aggiungi uno spazio dopo i "--", please ;)
David
-- 
 . ''`.  Debian maintainer | 
http://snipurl.com/gofoxygo/
 : :'  :  Linuxer #334216  |  
http://www.hanskalabs.net/
 `. `'`    GPG: 1392B174   | 
http://www.debianizzati.org/
   `-   2BAB C625 4E66 E7B8 450A C3E1 E6AA 9017 1392 B174

dovrebbe posizionarsi allo stesso livello, ma un livello sotto).
Aaaah, ecco, ora ho capito. Stasera mi ci metto, e' interessante. (Ho
un'idea di come fare, ma mi sa che sia troppo da forza bruta).


 Aggiungi uno spazio dopo i "--", please ;)
Ahiaaa....ero convinto di averlo messo (si vede ke è da tanto che non 
scrivo qui) LOL!!!
--
rob4you

 un'idea di come fare, ma mi sa che sia troppo da forza bruta).
Pendo dalle tue labbra. LOL
In effetti la questione è davvero interessante (almeno per me ;) ).
Intanto continuo a pensare anche io (anche se ormai i due neuroni hanno 
chiuso per surriscaldamento!).
--
rob4you

[CUT]
ehi ma io lo metto lo spazio nella firma....che caspita succedeeee...mi 
è impazzito l'editor! :)
--
rob4you

 array("accessori" => array()));
Da dove ti arrivano questi valori?
Devi per forza avere questa forma degli array, o li puoi elaborare prima 
(magari sono in XML, o dentro un DB, o che so io)?
Bye.

 (magari sono in XML, o dentro un DB, o che so io)?
Ottima domanda. :)
Sostanzialmente tutto ha origine con un file OWL, che può essere anche 
parecchio complesso (cioè contiene ben altre informazioni oltre le 
semplici relazioni classi-sottoclassi).
Per "mia" comodità, parso questo file OWL (che alla fine è un file XML 
"particolare", anche molto elaborato), e inserisco le semplici 
relazioni classe-sottoclasse in una tabella di un db (contenente, tra 
gli altri campi, proprio un campo CLASS e un campo SUBCLASSOF).
Successivamente vorrei appunto ottenere un array come quello di cui 
parlavo nei post precedenti.
Avevo anche pensato di passare da un file XML intermedio, del tipo:
<abitazione>
   <stanza>
      <camera_da_letto>
         <camera_da_letto_singola />
         <camera_da_letto_matrimoniale />
      <camera_da_letto>
      <salone />
   </stanza>
   <accessori>
      ...
   </accessori>
</abitazione>
e parsarmelo, al fine di ottenere l'aray voluto, ma non ho approfondito 
il discorso.
A dir la verità oggi una soluzione (non passante per l'xml intermedio) 
la avrei trovata, pare funzionante...magari prima di postarla faccio 
altre prove. ;)
--
rob4you

 Idee?
[..]
mi sembra pericoloso affidarsi cosi' alla costruzione di una struttura
gerarchica come questa basando le discendenze su una analisi dei valori in
entrata..
cosa succede se arriva qualcosa del genere?
$ar1 = array("stanza" => array("abitazione" => array()));
$ar2 = array("abitazione" => array("stanza" => array()));
saranno le stanze a contenere abitazioni, saranno le abitazioni a contenere
le stanze o saranno vere entrambe le ipotesi?
potrebbero generarsi ricorsioni non volute nella struttura..
le hai chiamate CLASS e SOTTOCLASSI..
perche' allora non usi le classi per elaborare queste strutture?
class house
{ function add_room ($room) {...}
  function add_lux ($lux) {...}  }
class room { function set_size ($size) {...} }
class bathroom extends room
{ function set_type ($bath_type) {...} }
class bedroom extends  room
{ function add_bed ($bed) {...} }
class bed { function set_type($bed_type) {...} }
class lux { function set_type ($lux_type) {...} }
devi definire la struttura prima.. nel modo che preferisci e' chiaro.. od
assicurarti che gli array di input siano particolarmente ordinati..
altrimenti passa come ti e' gia' stato suggerito ad un file xml..
-- 
www.iuz-lab.info
 - 
www.php-faq.org

 altrimenti passa come ti e' gia' stato suggerito ad un file xml..
Si, come già detto ci avevo pensato, ma non mi ero messo all'opera. In 
compenso forse avrei trovato una soluzione. Non sono molte righe, non 
dico nulla quanto a efficienza LOL né funzionamento.....almeno non 
prima di capire se va bene o meno! ;)
-- 
rob4you

chiuso per surriscaldamento!).
Sostanzialmente quello che hai definito e' una Knowledge Representation,
una serie di relazioni is_a  multiple. E tu vuoi cercare l'albero basato
sulla rappresentazione piu' compatta.
Quindi hai addirittura TRE problemi: riversare i vari array in una lista
di relazioni is_a; compattificarle eliminando le ridondanze, tipo:
	socrate ISA uomo
	uomo ISA mortale
	socrate ISA mortale --> ridondante
...poi espanderle in un albero con le definizioni.
Non so. Se c'e' un sistema piu' semplice e mi sono perso in un bicchiere
di Cardinal, saro' lieto di saperlo. O forse, si puo' accelerarlo usando
le funzioni per gli array ricorsivi.
Se no posso buttare giu' du' righe del modo brutale [1] :-)
Leonardo
[1] non meno di 120


 
se proprio sei sicuro dell'input.. e vuoi procedere cosi'.. vedo di
scriverti due righe stasera.. avevo gia' risolto un problema simile..
intanto continua a sbatterci la testa tu :-)
-- 
www.iuz-lab.info
 - 
www.php-faq.org

gli altri campi, proprio un campo CLASS e un campo SUBCLASSOF).
Accidenti a te, cosi' era MOLTO piu' facile!
Comunque, partendo da classe->sottoclasse, tirare fuori l'albero e'
pressoche' immediato. Se tte serve... :-)
Leonardo


 Se no posso buttare giu' du' righe del modo brutale [1] :-)
Riporto le righe che ho buttato io, sono una ventina effettive in 
tutto.
Non le ho commentate, vabbé, se vi va di vederne il funzionamento fate 
copie e incolla, non prima di aver creato una tabella in un db chiamata 
'owl_classi' con almeno due campi chiamati 'class' e 'subclassof', e 
averla riempita di coppie.
Se non vi va vedo di inviarvi un array già pronto, in modo che non 
dovete riempire nulla. :)
Ecco comunque il codice:
<?php
$sql = "SELECT Class,subClassOf FROM owl_classi ORDER BY subClassOf";
$result = mysql_query($sql);
if(!$result) die("Error: ".mysql_error());
$ar = array();
while ($row = mysql_fetch_assoc($result))
   $ar[] = array($row["subClassOf"] => array($row["Class"] => 
array()));
$temp = array();
foreach($ar as $v)
	$temp[] = reset(array_keys($v));
foreach($ar as $key=>&$val) {
	foreach($temp as $temp_k => $temp_v) {
		if($key == $temp_k) continue;
		if($temp_v == key(current($val)))
			$val[key($val)] = 
@array_merge_recursive($val[key($val)],$ar[$temp_k]);
		else if($key < $temp_k) continue;
		else if($temp_v == key($val))
			$val = @array_merge_recursive($val,$ar[$temp_k]);
	}
}
//Estrae array finale
$max = 0;
foreach($ar as $c => $a) {
	if(($m = count($a,COUNT_RECURSIVE)) > $max) { $max = $m; $indice = 
$c;}
}
print_r($ar[$indice]);
?>
-- 
rob4you

 pressoche' immediato. Se tte serve... :-)
Se non ti richiede troppa rottura, sarei felice di vedere la tua idea!
-- 
rob4you

rob4you ha spiegato il 27/09/2007 :
[CUT]
Alla fine ho effettuato anche la strada passando da un xml intermedio.
In questo caso non è stato troppo difficile.
Posto il codice utilizzato; ho dovuto riscrivere una funzione 
"banalissima" (5 righe di codice) per convertire un xml in un array, in 
quanto quelle trovate sulla guida non facevano al mio caso.
In pratica, la maggior parte del codice (che comunque è piccolo) prende 
i dati dal DB e crea un documento XML.
Infine, la funzione xml2array, fa quello che chiedevo inzialmente.
<pre>
<?php
require_once //inserire lo script dei parametri di connessione al db
$sql = "SELECT Class,subClassOf FROM owl_classi";// ORDER BY 
subClassOf";
$result = mysql_query($sql);
if(!$result) die("Error: ".mysql_error());
$dom = new DOMDocument('1.0', 'iso-8859-1');
while ($row = mysql_fetch_assoc($result)) {
	if($row["subClassOf"] == '') continue;
	if($sub = ($dom->getElementsByTagName($row["subClassOf"])->item(0))){
		if($cl = $dom->getElementsByTagName($row["Class"])->item(0)) {
			$sub->appendChild($cl);
		}
		else {
			$class = $dom->createElement($row["Class"]);
			$sub->appendChild($class);
		}
	}
	else {
		if($cl = $dom->getElementsByTagName($row["Class"])->item(0)) {
			$subclass = $dom->createElement($row["subClassOf"]);
			$dom->appendChild($subclass);
			$subclass->appendChild($cl);
		}
		else {
			$subclass = $dom->createElement($row["subClassOf"]);
			$n = $dom->appendChild($subclass);
			//$n->setAttribute("align", "left");
			$class = $dom->createElement($row["Class"]);
			$subclass->appendChild($class);
		}
	}
}
echo htmlentities($dom->saveXML());
function xml2array($n,&$ar) {
	if($n->hasChildNodes()) {
		$figli = $n->childNodes;
		foreach($figli as $f) {
			$ar[(string)$f->tagName] = array();
			xml2array($f,$ar[(string)$f->tagName]);
		}
	}
}
$arr = array();
xml2array($dom,$arr);
print_r($arr);
?>
</pre>
-- 
rob4you

 Infine, la funzione xml2array, fa quello che chiedevo inzialmente.
Ormai hai risolto in 12000 modi... questo è quello con gli array:
<?PHP
function crea_array(&$nodo, $i) {
  if ($nodo['padre'][$i] === null)
    $ar = array();
  else
    $ar = array("{$nodo['corrente'][$i]}" => $nodo['contenuto'][$i]);
  if ($nodo['figlio'][$i] !== null) {
    $appo = crea_array($nodo, $nodo['figlio'][$i]);
    foreach($appo as $key => $value)
      $ar["{$nodo['corrente'][$i]}"]["{$key}"] = $value;
  }
  if ($nodo['fratello'][$i] !== null) {
    $appo = crea_array($nodo, $nodo['fratello'][$i]);
    foreach($appo as $key => $value)
      $ar["{$key}"] = $value;
  }
  return $ar;
}
$ar1 = array("stanza" => array("camera_da_letto" => array()));
$ar2 = array("abitazione" => array("stanza" => array()));
$ar3 = array("stanza" => array("salone" => array()));
$ar4 = array("abitazione" => array("accessori" => array()));
$ar5 = array("camera_da_letto" => array("letto" => array()));
$ar6 = array("abitazione" => array("balcone" => array()));
$ar7 = array("stanza" => array("bagno" => array()));
$ar8 = array("letto" => array("lenzuola" => array()));
$tot_array = 8;
$nodo['padre'][0] = null;
$nodo['corrente'][0] = null;
$nodo['contenuto'][0] = array();
$nodo['fratello'][0] = null;
$nodo['figlio'][0] = null;
for ($i=1; $i<=$tot_array; $i++) {
  list($nodo['padre'][$i], $elemento) = each(${"ar$i"});
  list($nodo['corrente'][$i], $nodo['contenuto'][$i]) = each($elemento);
  $nodo['fratello'][$i] = null;
  $nodo['figlio'][$i] = null;
}
array_multisort($nodo['padre'], SORT_ASC,
                $nodo['corrente'], SORT_ASC,
                $nodo['contenuto'],
                $nodo['fratello'],
                $nodo['figlio']
);
for ($i=1; $i<=$tot_array; $i++) {
  if ($nodo['padre'][$i] === $nodo['padre'][$i-1])
    $nodo['fratello'][$i-1] = $i;
  elseif ($a = array_search($nodo['padre'][$i], $nodo['corrente']))
    $nodo['figlio'][$a] = $i;
  elseif ($nodo['corrente'][0] === null) $nodo['figlio'][0] = $i;
}
$nodo['corrente'][0] = $nodo['padre']["{$nodo['figlio'][0]}"];
$ar = crea_array($nodo, 0);
echo '<pre>';
echo "ar:\n";
print_r($ar);
echo '</pre>';
?>

 come le costanti che non lo sono e le variabili che non lo fanno :-)
I tuoi commenti mi fanno sempre morire! :)
Comunque grazie a entrambi.....più tardi mi metto a dare un'occhiata al 
funzionamento, così vedo di capirne i "segreti". ;)
-- 
rob4you

I tuoi commenti mi fanno sempre morire! :)
Di solito non sono miei. Questa per es. e' la legge di Osborn.
http://www.sysprog.net/quotlaws.html
 (quasi tutte sono serie)
Leonardo plagiaro
