Ver Mensaje Individual
  #6 (permalink)  
Antiguo 01/07/2013, 03:02
Avatar de Italico76
Italico76
 
Fecha de Ingreso: abril-2007
Mensajes: 3.303
Antigüedad: 17 años, 7 meses
Puntos: 292
Respuesta: Iterador se rebobina [Ggrrr]

Cita:
Iniciado por repara2 Ver Mensaje
ok, pero entonces cuál era el problema? Puedes postear la solución?
Revisando el codigo... de pronto si rebobina el while() tambien jeje ...en fin...

Código PHP:
<?php
namespace FastyPatterns


interface 
IComparable
{
   
/**
    * Hace comparacion como
    * su homologa en C#    
    * 
    * @return int {-1,0,1}
    */
   
public function compareTo($other);

   public function 
getDiff();
}

abstract class 
Comparable implements IComparable
{
    protected 
$_diff = array();

    
/**
     * Devuelve diferencias
     *      
     * @return array
     */
    
public function getDiff ()
    {
      return 
$this->_diff;    
    } 

}

/**
 * Tag: 
 *      almacena un tag con todas sus propiedades
 */
Class Tag extends Comparable
{
    private 
$_element_name null;  // input-text, input-radio,...etc
    
private $_prop = array();

    public function 
__construct($element){
        
$this->_element_name $element;
        return 
$this;
    }      

    public function 
getElementName(){
        return  
$this->_element_name;
    }
 
    
// (objeto)->propiedad = valor   (no es encadenable)
    
public function __set($p,$val)
    {          
        
$this->_prop[$p]= $val;            
    }
  
    public function 
__get($p)
    {  
        return 
$this->_prop[$p];

    } 
// end class

   
    // (objeto)->set_propiedad(valor)   (si es encadenable)
    
public function __call($name$arguments) {

        
// setting a property
        
if (substr($name,0,4) == 'set_') {

            
// get the property name we want to set
            
$property substr($name,4);
            
// assign the value that was passed to this method
            // to the class property
            
$this->_prop[$property] = $arguments[0]; 
            
//var_dump($this->_prop);

        // adding to an array property
        
} else if (substr($name,0,4) == 'add_') {

            
// get the property name we want to add to
            
$property substr($name,4);
            
// add the value
            
array_push($this->_prop[$property], $arguments[0]);

        }

        
// for method chaining
        
return $this;
    }

    public function 
getAllFormated(){
        
$out "Tag: {$this->_element_name} <br/>";
        foreach (
$this->_prop as $prop => $val){
            
$out .= "[$prop] => $val <br/>";
        }
        return 
$out.'<p/>';
    }

    public function 
__ToString()
    {
        return 
$this->getAllFormated();
    }

    
// es revelar el estado interno, pero es lo mas facil
    
public function getProperties(){
        return 
$this->_prop;
    }
   
     
    
/**
    * Compara Tags: variacion de metodo de C# 
    *
    * @return {-1 ,0 , 1} 
    *
    * si el tipo de elemento es distinto, retorna -1    
    * si son iguales, retorna 0
    * si el primero tiene algo de sobra, retorna 1
    */
    
public function compareTo ($tag2)
    {
    
        
$class __CLASS__;
        if (!(
$tag2 instanceof $class))
            throw new 
Exception ('Debe ser del mismo tipo a comparar'); 

        
$this->_diff null;
        

        
// seguro distintos tags y ya
        
if (strtolower($this->getElementName()) != strtolower($tag2->getElementName()))
            return -
1;  

        
$p1 $this->getProperties();
        
$p2 $tag2->getProperties();     

        
// seguro son iguales en todo
        
if ($p1 == $p2)
            return 
0;    

        
// sera que hay en tag2 elementos que no estan en este ?
        
$this->_diff array_diff_assoc ($p2,$p1);
        if (
count($this->_diff)!=0)
            return -
1;

        
// sera que hay en este tag elementos que no estan en tag2 ?
        
$this->_diff array_diff_assoc ($p1,$p2);
        if (
count($this->_diff)!=0)
            return 
1;

        throw new 
Exception ('Fallo al capturar diferencia de tags'); 
    }

// end class



/**
 *   TagSequence:
 *                almacena una secuencia de tags  
 */
Class TagSequence implements Iterator
{
    private 
$_name null;
    private 
$_tags = array();
    private 
$_optionals = array();

    private 
$_last_search =null;
    private 
$_search_cursor =null;


    public function 
__construct($name=null){
        
$this->_name $name;
        return 
$this;
    }      

    public function 
setName($input)
    {
        
$this->_name=$input;
        return 
$this;
    }

    public function 
getName()
    {
        return 
$this->_name;
    }
 
    public function 
addTag (tag $tag $optional=null){
        
$this->_tags[]=$tag;              
        
$this->_optionals[]=$optional;      
        return 
$this;
    }

    
// devuelve si el tag actual en la secuencia esta marcado como opcional o no 
    
public function is_optional(){
        return 
$this->_optionals[$this->key()];
    }  

    public function 
__ToString ()
    {
        
$out '<i><b>Secuence:</b> '.$this->_name.'</i><p/>';
        foreach (
$this->_tags as $tag){
            
$out .= $tag->getAllFormated();
        }
        return 
$out.'<p/>';
    }

    
/* Find:  mueve el cursor hasta la primera ocurrencia o hasta el final sino se encuentra devuelve bool
    *  
    *  El cursor queda sobre el elemento seleccionado o en NULL si llega al final sin encontrarlo
    *  Permite buscar varias ocurrencias si se repite la busqueda
    */
    
public function find(tag $search,$continue=true){     
        if (
$continue and $search==$this->_last_search)
        {           
           while (
$this->valid() and $this->key()<=$this->_search_cursor){
               
$this->next();
           }           
        }
           
        
$this->_last_search $search;  

        while (
$this->valid()){
            
$current_tag $this->current();
            
$this->_search_cursor $this->key();  

            if (
$current_tag->compareTo($search)>=0){
                return 
true;                
            } 
            
$this->next(); 
                      
        }  
        return 
false;
    }



    
/**
     * findFirst : busca la primera ocurrencia
     * 
     * a) Es mas eficiente
     * b) Siempre busca *desde el comienzo* 
     * c) el cursor queda 'pasado' en 1 o o en NULL si llega al final sin encontrarlo 
     *
     * @param tag 
     * @return bool
     */
    
public function findFirst(tag $search){     

        
$ret false;

        foreach (
$this->_tags as $key=> $current_tag)
        {
            if (
$current_tag->compareTo($search)>=0){
                
$ret True;                                    
                break;
            }             
        }          
        
        return 
$ret;      

    }



    
/* Implemento interface Iterator  */

    
public function rewind()
    {        
        
reset($this->_tags );
    }

    public function 
current()
    {
        
$tag current($this->_tags);        
        return 
$tag;
    }

    public function 
next()
    {
        
$tag next($this->_tags );        
        return 
$tag;
    }
  
    public function 
key()
    {
        
$tag_key key($this->_tags ); 
        return 
$tag_key;
    }
  
    public function 
valid()
    {
        
$key key($this->_tags );
        
$tag = ($key !== NULL && $key !== FALSE);        
        return 
$tag;
    }


// end class
Las pruebas no me entraron.......exceden los 10.000 caracteres

No me pegues, despues de tanta vuelta olvide que fue lo que hice aunque creo que el funcionamiento ya se puede asegurar
__________________
Salu2!