Newsgroup: it.comp.www.php
Titolo: Sapere se un array è associativo

E' possibile sapere se un array appena creato è associativo o meno?
Cioè se è specificato così:
$array = array("indice"=>"valore", "indice"=>"valore");
e non così:
$array = array("valore", "valore");
Verificare che gli indici vadano da 0 a x (come presunta dimostrazione
che si tratta di un array non associativo) non è una soluzione che mi
piace, in quanto "non sicura".


Potresti definire un array associativo come un array in cui esiste
almeno una chiave alfanumerica e non numerica.
Detto ciò la funzione di controllo potrebbe essere la seguente:
function IsAssociativo($arrInput)
{
       $retVal=false;
       foreach($arrInput as $k=>$v)
        {
               if (!is_numeric($k)) $retVal=true;
        }
      return $retVal;
}
Ciao,
     Fabrizio
=== 
http://www.negusweb.it
 ===

 piace, in quanto "non sicura".
Chiariamo: gli indici possono essere int e/o string. Gli array del PHP
sono sempre "associativi" nel senso che associano un int o una string a un
elemento. Internamente gli indici non hanno un ordine particolare, cioe'
non sono 0, 1, 2, ... Verificare questo mi sembra molto pesante, meglio
crearli gia' nel modo corretto.
Ciao,
 ___ 
/_|_\  Umberto Salsi
\/_\/  
www.icosaedro.it



Ah, si può ottimizzare ancora fermandosi al primo elemento con chiave
alfanumerica, ovvero:
function IsAssociativo($arrInput)
{
        $retVal=false;
        $k=0;
        $arrK=array_keys($arrInput);
        while (($k<sizeof($arrK)) && (!$retVal))
        {
                 if (!is_numeric($arrK[$k])) $retVal=true;
                 $k++;
        }
        return $retVal;
}
Ciao,
       Fabrizio

 Detto ciò la funzione di controllo potrebbe essere la seguente:
Grazie, ma non è quello che mi serve. Potrebbe essere stato l'utente
stesso ad aver definito degli indici numerici.



Ma la tua domanda era questa:
<quoto>
E' possibile sapere se un array appena creato è associativo o meno?
</quoto>
A questo punto potrebbe essere stato sempre l'utente a definire gli
indici alfanumerici.
Qual è il tuo scopo?
Ciao,
    Fabrizio

 crearli gia' nel modo corretto.
E' vero che gli array di php sono sempre associativi, ma tale
associazione può essere esplicitata nello script al momento della
creazione dell'array, oppure eseguita dal motore di php in modo
automatico quando l'array è creato solo mediante una successione di
valori. In quest'ultimo caso gli indici sono interi univoci che
partono da 0 e arrivano a x. E' possibile distinguere se l'array è
stato creato esplicitando l'associazione o meno?

 Qual è il tuo scopo?
Sì, forse era più chiaro se avessi spiegato da subito il problema
concreto :-)
Ho una classe che crea una select in html
Le varie option della select sono prese da una proprietà della classe
(di tipo array), il cui contenuto è definito in una pagina di
"configurazione".
$select->new select();
$select->setOptions(array("etichetta1"=>"valore1",
"etichetta2"=>"valore2"));
L'array da passare al metodo setOptions è definito espicitando
l'associazione indice => valore
Il metodo show() si occuperà di ciclare l'array e visualizzare la
select in questo modo
foreach ($this->options as $etichetta => $valore) {
  echo("<option value="$valore">$etichetta</option>");
}
Ovviamente la proprietà $this->options contiene l'array passato col
metodo setOptions.
Se l'array passato a setOptions non è definito esplicitando
l'associazione, ma solo come successione di valori, il contenuto
dell'attributo value nel tag option sarà un indice numerico impostato
in automatico (0, 1, 2, e così via). Io invece vorrei che se
l'associazione non è esplicitata, ogni elemento dell'array sia
trattato dal metodo show() sia come valore che come etichetta del tag
option. Se perciò l'associazione non è esplicitata, il ciclo per la
visualizzazione dei tag option sarebbe:
foreach ($this->options as $valore) {
  echo("<option value="$valore">$valore</option>");
}
Ma non potendo distinguere in che modo è stato definito l'array, non
posso risolvere il problema
Spero sia chiaro :-)

 stato creato esplicitando l'associazione o meno?
no e quello che hai detto puo' non essere vero..
-- 
www.iuz-lab.info
 - 
www.php-faq.org

 stato creato esplicitando l'associazione o meno?
No, l'array non contiene nella sua pancia questa informazione. Se non metti
la chiave esplicitamente, lui mette gli indici int a partire da zero, infatti
array("zero")
e
array( 0 => "zero" )
risultano identici.


 Spero sia chiaro :-)
L'unico modo è controllare se l'array è associativo, come ti ho
proposto.
Ciao,
    Fabrizio

 Spero sia chiaro :-)
Esattamente, non puoi.
L'unica costa che puoi fare è creare un'altro setOptions con un'altro  
nome, che faccia quel lavoro lì.
Oppure creare qualche tipo di convenzione tramite API.
Puoi decidere ad esempio che tutti gli array siano chiave valore. E  
decidere che per usare come chiave il valore della proprietà tu debba  
passare un'oggetto.
$select->setOptions( array ( 'a', 'b', 'c' ) ); // <option name="a"  
value="1" />
$select->setOptions( (object)array( 'a', 'b', 'c' )); //<option name="a"  
value="a" />
...
function setOptions( $options )
{
	if ( is_object( $options ) )
	{
		$new = $options;
		foreach ( $options as $v ) $new[ $v ] = $v;
		$options = $new;
		unset( $new );
	}	
	...
}
Ci sono altre opportunità che hai, sempre a livello di api, ad esempio:
$select->setOptions ( quickOptions( 'a', 'b', 'c' ) );
Ciao
Tac
-- 
Using Opera's revolutionary e-mail client: 
http://www.opera.com/mail/