Newsgroup: it.comp.lang.javascript
Titolo: Riconoscere un array: come?

Mentre preparavo una nuova FAQ per il sito (una funzione per clonare un 
array) mi son trovato davanti un problema con Netscape4.
Ho una struttura di questo tipo:
var ar = new Array()
	ar[x]="Elem 0";
	ar[y]=new Array();
		ar[y][a] = "Elem 1 0";
		ar[y][b] = "Elem 1 0";
	ar[z]="Elem 2";
document.write(ar[x].length+"<BR>");
document.write(ar[y].length+"<BR>");
document.write(ar[z].length+"<BR>");
NOTA: invece degli indici ho usato delle variabili. A priori infatti suppongo 
di non sapere qual'e' l'indice di un determinato elemento dell'array, visto 
che con JavaScript e' possibile avere posizioni vuote.
I tre document.write() restituiscono "correttamente" le lunghezze: il primo 
ed il terzo restituiscono il valore "6" che e' la lunghezza della stringa-
elemento, mentre il secondo restituisce "2" che e' la lunghezza dell'elemento 
quindi la dimensione dell'array ar[y].
Il problema e': come faccio a capire che ar[y] e' un array e non una stringa?
Ho gia' provato ad usare join(""), ma per ar[x] e ar[z] da un errore perche' 
non sono array, ed ho provato anche questo:
for (el in ar[-])
	document.write(ar[-][el]);
Il problema e' in N4: questo ciclo for eseguito sull'elemento [y] restituisce 
le singole lettere della stringa come se fossero elementi di un array.
Ovviamente non posso usare try() catch{} perche' non andrebbe con N4.
Questo e' lo script di prova (commentato):
-------------------------------------------------------------------------
<HTML>
<BODY BGCOLOR="#ffffff">
<SCRIPT>
// Array di prova, gli elementi 6,7,8 non esistono, 2 e 10 sono array
var ar = new Array("a",new Array("baba","ngng"),"c","pippo","d","e")
	ar[9]="nove";
	ar[10] = new Array("dieci","undici","dodici");
document.write("<hR>")
var arcopia=new Array(); // Il nuovo array dichiarato
Clone(ar,arcopia); // Chiamata della funzione di copia
// --- Ok, se ne puo' fare un metodo, ma per adesso sorvoliamo! :-) --- //
document.write("<hR>")
// I due array vengono visualizzati:
document.write("ar = "+ar+" <BR>arcopia = "+arcopia+"<hR>")
// L'elemento [10][1] clonato viene visualizzato:
document.write("<STRONG>"+arcopia[10][1]+"</STRONG><BR><hR>")
/* Questo serve per verifica: se e' stato generato un nuovo array il 
risultato sara'
                      u,n,d,i,c,i
ed e' quel che succede con N4, altrimenti sara' correttamente la parola 
"undici" */
 
// L'intero array clone viene visualizzato
for (i=0;i<arcopia.length;i++)
	arcopia[i]?document.write(i+" - "+arcopia[i]+"<BR>"):null;
/* Anche qui N4 genera per l'elemento 3 (pippo -> p,i,p,p,o) un clone che e' 
un array con tutte le lettere, idem per l'elemento nove (nove -> n,o,v,e) e 
l'elemento 10 e' diventato un array di array ... :-( */
 
// --- Funzione di copia --- //
/* Il problema sta nella variabile "cnt", N4 si comporta come ho scritto 
all'inizio del post Sempre per quanto scritto sopra non e' possibile usare 
"length" perche' restituirebbe la lunghezza dell'elemento se e' una stringa,
e la lunghezza dell'array se e' un array per questo motivo ho inserito un 
contatore, ma con N4 si comporta "male" */
function Clone(a,b)
	{
	for (_Clone in a)
		{
		var cnt=-1;
		for (c in a[_Clone])
			cnt++;
		if (cnt>1)
			{
			b[_Clone]=new Array();
			Clone(a[_Clone],b[_Clone]);
			}
		else
			b[_Clone] = a[_Clone]
		}
	}
</SCRIPT>
</BODY>
</HTML>
Sono in un periodo di sfiga... help me! :-))
-- 
Ciao, Riccardo
------------------------------------------------------------------------
http://www.jsdir.com
 ---- Bring Your Site To Life!!!!
------------------------------------------------------------------------
http://www.dev2dev.it
 - La rete ha connesso nuove particelle - D2D006
------------------------------------------------------------------------
 ----> itALY = it <----

 array) mi son trovato davanti un problema con Netscape4.
[...]
Domanda al volo: poni dei limiti?
Se ho ben capito vuoi copiare un array per valore invece che per
riferimento.
Visto che possiamo avere n array di array e che gli array possono anche
contenere altri oggetti la situazione diventa ben più complessa.

 un array e non una stringa?
typeof() non va bene?
Maurizio.

 Il problema e': come faccio a capire che ar[y] e' un array e non una
stringa?
Se ho capito il problema, posso picchiarvi tutti e tre?
Te per la domanda, Andrea per le "complicazioni affari semplici".. No,
Maurizio no, perche' cmq una risposta l'ha data e in questo caso era
applicabile alla maggior parte dei casi (il problema del typeof, e' che ti
restituisce "object" per ogni tipo di oggetto.. compreso il null).
Cmq, Riccardo.. utilizza la proprieta' constructor, 'tupidone.. :)
if (a[y].constructor==Array){alert("O mio dio, ma questa variabile e' un
oggetto generato dalla classe Array!")}else{alert("Mi e' andata bene..")}
Ovviamente, se non ho capito la domanda, per par condicio, picchiami pure
tu.. :D
--------------------------------
Inviato via 
http://usenet.libero.it

 le singole lettere della stringa come se fossero elementi di un array.
E fa bene.. e' IE che ha deciso di andare controcorrente.. (tanto per
cambiare).
Per farti un esempio, i C la stringa in senso lato non esiste. La stringa
non e' altro che un array di caratteri, oppure puoi fare un puntatore char
che punta ad una locazione di memoria con "n" caratteri sequenziali (arra e
puntatori.. siam sempre li' cmq..).
E, difatti, una stringa cos'e' se non una lista (ovvero array) di caratteri?
:)
Ed e' molto comodo poterci accedere in questo modo..


 "object" per ogni tipo di oggetto.. compreso il null).
Hai ragione, però a Riccardo interessava distinguere solo l'array dalla
stringa, non dagli altri oggetti.
typeof(stringa) riporta String, mentre typeof(array) riporta Object.
Maurizio.

 typeof(stringa) riporta String, mentre typeof(array) riporta Object.
Per esattezza riporta "string" e "object" (fa differenza e poi io sono
"famoso" per la mia meticolosita'), inoltre nell'ipotesi che tu abbia una
stringa generata da String() o da una funzione che ti restituisce una
stringa della classe String(), typeof ti risponde "object" in entrambi i
casi, quindi puo' essere fuorviante.
Inoltre, se hai un elemento "null", lui lo considererebbe come un array e
tenterebbe di clonarlo.
Insomma, a mio avviso la soluzione del typeof lascerebbe troppi "bachi"
aperti, e non si presta per realizzare una funzione del genere.
Il constructor e' esattamente la proprieta' che serve in questi casi, anche
perche' puoi distinguere le varie classi e operare di conseguenza.
Esempio, clonando per VALORE i vari Number, String, Array, e bypassando
tutto il resto.. ovvero null e eventualmente oggetti per riferimento.


 tu.. :D
Nel caso "picchiatemi pure voi". Amo il plurale quando serve.


Se stringa e' un valore letterale.
var s= new String("pippo");
alert( typeof s);
Restituisce object.

 in entrambi i casi, quindi puo' essere fuorviante.
i famosi oggetti wrapper... si chiamano cosě anche in js?
Siete stati chiarissimi, sia tu che Andrea.
Maurizio.

 i famosi oggetti wrapper... si chiamano cosě anche in js?
Beh, penso che sia una dicitura abbastanza universale, no? Io ho creato
proprio dei wrapper di recente, per Domino.. un bordello -_-


 Siete stati chiarissimi, sia tu che Andrea.
Thanks

 Beh, penso che sia una dicitura abbastanza universale, no?
Non si sa mai. Come dice Gary Cornell nel suo libro sul Java: "Naturalmente
i moderni linguaggi di programmazione considerano motivo di orgoglio
introdurre una nuova terminologia..."
Maurizio.

, 
ascartab...@codice.it
 
says...

No, penso solo a degli array (di array... di array... ecc.) che contengano 
solo dei valori di tipo stringa o numerici, non oggetti.
Quel che voglio fare è l'analogo di questo:
var a = "pippo";
var b = a; --> b = "pippo"
dato un array voglio _clonarlo_ per ottenerne una copia come b=a


, mau...@libero.itA 
says...

Non ci avevo pensato :-))
Ora leggo il thread di Zer0 e vedo...


 stringa?" hai ragione in pieno.
Esattamente questo era il problema... Ok, ora che finisco di smanettare con 
Apace/PHP/mySQL ci riprovo :-)
Thanks a tutti.


 Ed e' molto comodo poterci accedere in questo modo..
In effetti N4 a quanto ho visto si comporta esattamente cosě.
Ok grazie anche a te... ora vedo di romperti un po' le scatole con PHP/mySQL 


 [... megaCut ...]
Per la cronaca, questo e' lo script funzionante grazie all'intuizione di 
Zer0:
function Clone(_ArryToClone)
   {
   var _Clone = new Array();
   for (_IdClone in _ArryToClone)
      if (_ArryToClone[_IdClone].Constructor == Array)
         Clone(_ArryToClone[_IdClone])
      else
         _Clone[_IdClone] = _ArryToClone[_IdClone]
   return _Clone
   }
Per duplicare un array "pippo" in "pluto" basta fare: 
var pluto = Clone(pippo);
n.b.
Questa duplica solo un array composto da stringhe, l'ipotesi di Andrea 
(qualche elemento dell'array contiene altri tipi di oggetti) non l'ho 
sviluppata.
--------------------------------------------------------
Ora la domanda del lunedi' mattina :-)
Ero partito in quarta con questo scriptino per due motivi:
1.- vedere se riuscivo a creare una funzione ricorsiva;
2.- sopperire ad una presunta mancanza.
Per il primo punto: OK, pensavo chissa' che :-))
Per il secondo punto: sul piu' bello che stavo scrivendo la faq esordendo con 
"in JavaScript non e' possibile usare = per assegnare ad una variabile un 
array gia' definito e copiarlo", faccio due prove (N4 e Mozilla) e resto di 
sasso: l'arry copia e' perfettamente identico al primo (sempre limitatamente 
ad elementi stringa)!!!
Come non detto, ho sollevato un polverone per niente, ma almeno ho imparato 
ad usare "constructor" :-))


 ad usare "constructor" :-))
Sara' anche il lunedi' mattina.. quindi, ho sono io che sono mezzo
"rincretinito" o sei tu.. direi che, visto le ns condizioni, entrambi le
ipotesi potrebbero essere vere.. :)
Ma, visto che l'Array e' un oggetto, se utilizzi l'operatore di
assegnazione, non fai una copia ma un riferimento :)


 assegnazione, non fai una copia ma un riferimento :)
Gia', forse era questo... il fatto e' che nell'ormai immenso file di testo 
sul mio desktop "IdeePerJsdir.txt" ho "come si copia un array?" ormai da mesi 
non ricordo piu' perche' l'avevo scritto :-(
[OT]
Ho postato una richiesta in it.comp.www.php hai mica idea di come risolvere?


 Ho postato una richiesta in it.comp.www.php hai mica idea di come
risolvere?
Purtroppo no. Come unica fonte di masochismo ho scelto le donne :)
Installare PHP su Win98 non rientrava in questi piani, quindi non so che
dirti.. ^^
.. Inoltre, anche su Win2k/XP ho optato per far eseguire PHP a IIS..
(appro', sta uscendo Windows .NET Server Family.. con IIS6)


 (appro', sta uscendo Windows .NET Server Family.. con IIS6)
Ma come... finalmente mi sono deciso a "seguire i tuoi consigli subito invece 
che dopo anni" (libera citazione dalla tue e-mail) e mi vieni ancora a 
parlare di M$oft? :-))
Ma allora non e' vero che "con piaccapi' fai tutto meglio e prima"? ^_^
Tutti i piaccapippari dicono cosi' :-O


 Tutti i piaccapippari dicono cosi' :-O
Non confondere il "tifo" con la "professionalita' " ;)
Il motto di PHP e' "the right tool for the right job", ed e' anche il mio da
molto prima che PHP uscisse.. Nn si deve "sposare" ne' tantomeno "tifare" in
modo cieco nessuna tecnologia, ma usare quella piu' adatta alle diverse
situazioni. :)
Fossilizzarsi su una, senza dare uno sguardo alle altre, solo per partito
preso, e' la rovina per un professionista del settore.
BTW, tu adesso ti impari PHP.. ma se hai dato uno sguardo al sito, hai visto
che sta cambiando completamente engine e si sta orientando verso una
strutturazione diversa per diventare ancora piu' compatibile con altre
tecnologie come .NET e Java.
Nel "nostro lavoro" bisogna sempre mantenersi aggiornati.. ed essere
poliedrici. :)


Le funzioni ricorsive sono banali, basta stare attenti allo stack 
Ecco qua. sospettavo che il mio metodo sperainDio non fosse ottimale
ma potresti illuminarmi su come operativamente si opera per tenere
sotto controllo il piccolo demonio?
grazie 

, 
p.ca...@toglimitiscalinet.it
 says...

Per quel che mi riguarda basta mandare in palla due tre volte due o tre 
browser, riavviare (reset con successivo scandisk) quattro cinque volte, una 
decina di craniate contro lo spigolo e poi funziona... poca roba, un paio 
d'ore :-))


d'ore :-))
ah ecco, ma parrebbe il mio metodo sperainDio...
;-)

 ah ecco, ma parrebbe il mio metodo sperainDio...
Si, derivato (eredita i metodi ed alcune proprieta') da "Plug and pray" :-))


Si, derivato (eredita i metodi ed alcune proprieta') da "Plug and pray" :-))
stavo guardando il debugger fornito da mozilla 1.1 
ho visto una fugace apparizione di una quantificazione in caratteri
del buffer (vigliacco se riesco a capire come ho fatto a farmelo dire
e a ripetere l' operazione  )
ma se ci riesce lui perche' non, ehm vabbeh, qualcuno di voi?

 sotto controllo il piccolo demonio?
Non c'e' molto da illuminare, difficile che la tua funzione faccia casini se
e' codata bene (per questo, prima di eseguirla, bisogna aver fatto almeno
una piccola analisi se e' relativamente complessa, nella condizione di
uscita). Quando dico "stare attenti allo stack", in JS intendo "non fare una
funzione ricorsiva di 2mega di righe di script che ti alloca 4 mega di
variabili a passo su un PC che ne ha 64" :)
Sicuramente c'e' qualche tools/debugger che ti gestisce la cosa, ma
personalmente per quanto riguarda i browser non li ho mai utilizzati..
Al massimo, apro il taskman e vedo quanta memoria mi sta prendendo IE/NS.
Non ho mai studiato "come" viene gestito lo stack da Javascript/NS e
JScript/IE.. anche perche' essendo un ambiente di un certo tipo, non hai
bisogno di monitorare la gestione della memoria.. in quanto puntatori non ne
hai, l'allocazioni di memoria le gestisce lui, e un qualche tipo di gc pare
avercela.
.. Preferisco di gran lunga "perdere il mio tempo" su C++ a cercare di
bombare il sistema allocando i puntatori nei modi piu' strani =)


 assegnazione, non fai una copia ma un riferimento :)
Infatti, ecco il bandolo.
Premesso che l'array di partenza e' questo:
var ar = new Array("a",new Array("baba","ngng"),"c","pippo","d","e")
	ar[9]="nove";
	ar[10] = new Array("dieci",new Array("undici a","undici b","uncidi 
c","undicid"),"dodici");
Cioe' l'elemento [3] vale "pippo" e l'elemento [20] non esiste:
facendo:
var arcopia = ar;
e poi:
arcopia[20]="Riccardo";
arcopia[3]="PIPPO";
(cioe' nuovo elemento e modifica nella copia) ottengo:
                  originale         copia
----------------------------------------------------
 Elem 3           PIPPO            PIPPO
 Elem 20          Riccardo         Riccardo
Cioe' di fatto e' cambiato l'array originale e la copia punta sempre a 
quello.
Invece con 
var arcopia = Clone(ar);
e di nuovo:
arcopia[20]="Riccardo";
arcopia[3]="PIPPO";
il risultato e':
                  originale         copia
----------------------------------------------------
 Elem 3           Pippo            PIPPO
 Elem 20          undefined        Riccardo
Il che e' giusto.
Testato su (Win98):
- IE 5
- Moz 1.0
- NN 4.7
- Opera 5.12
===========================================================================
E con questo si conclude l'avventura ancora una volta grazie all'intervento 
risolutivo del grande Zer0 :-))
[no ironia :-) ]
Tnx, la faq va on-line in settimana.
