Source of packages/Combie/Math/Permutation/Array2Dim.php

<?php
/**
 * Permutationen 2 dim
 *
 * Vertauschen von Array Elementen
 *
 * @filesource
 * @author Combie <uli@combie.de>
 * @version $Id$
 * @package Combie
 * @subpackage Math
 */

namespace Combie\Math\Permutation;

/**
 * Permutation eines 2 dimensionalen Arrays
 *
 * Vertauschen von Elementen
 *
 * @example packages/Combie/tests/math/test_permutation_2dim.php
 * @package Combie
 * @subpackage Math
 */
class Array2Dim implements \Countable, \ArrayAccess, \Iterator
{

/**
 * Interne Variable
 * @var array interne Repräsentation
 */
  
private $array  = array();

/**
 * Interne Variable
 * @var interger Anzahl aller möglichen Vertauschungen
 */
  
private $count  0;

/**
 * Interne Variable
 * @var integer inter Zeiger für die ArrayAccess Schnittstelle
 */
  
private $pos    0;

/**
 * Permutation 2 Dim
 *
 * Interne Helfer Funktion
 * Erzeugt alle Permutationen eines ein Dimensionalen Arrays
 *
 * @param array Das Array mit den Elementen, welche vertauscht werden sollen
 * @return void Keine Rückgabe
 */
  
public function __construct(Array $array)
  {
    
$array        array_values($array); // normalisieren
    
foreach($array as $index => &$teilarray)
    {
      if(!
is_array($teilarray))
        throw new \
InvalidArgumentException('Only Arrays allowed',1);
      if(
count($teilarray) < 1)
        throw new \
InvalidArgumentException("Too few Elements in Subarray $index",2);
      
$this->array[$index]['data']  = array_values($teilarray); // normalisieren
      
$this->array[$index]['fence'] = 1// provisorisch
      
$this->array[$index]['count'] = count($teilarray);
    }
    for (
$i=count($this->array)-1;$i>0;$i--)
      
$this->array[$i-1]['fence'] = $this->array[$i]['fence']*$this->array[$i]['count'];
    
$this->count $this->array[0]['fence']*$this->array[0]['count'];
    if(!
is_int($this->count))
     throw new \
InvalidArgumentException('Too many elements for Integer Count',3);
  }

/**
 * Holt gezielt eine Vertauschung
 *
 * Diese Methode ist Teil der ArrayAccess Schnittstelle
 *
 * @param index Index der gewünschten Vertauschung
 * @return array Vertauschung
 */
  
public function offsetGet($index)
  {
    if(!
$this->offsetExists($index))
      throw new \
InvalidArgumentException('Offset out of Range',4);
    
$result = array();
    foreach(
$this->array as &$teilarray)
    {
      
$result[] = $teilarray['data'][floor($index/$teilarray['fence'])];
      
$index    $index $teilarray['fence'];
    }
    return 
$result;
  }
  
 
/**
 * Vollständige Permutation eines 2 Dimensionalen Arrays
 *
 *
 *
 * @param array Das Array mit den Elementen, welche vertauscht werden sollen
 * @return array Ein Array mit allen möglichen Vertauschungen
 */
  
public static function getAll(Array $array)
  {
    
$result = array();
    foreach(
$array as $subarray)
    {
      
$zwischenlager = array();
      if(empty(
$result))
        foreach(
$subarray as $element)
          
$zwischenlager[] = array($element);
      else
        foreach(
$result as $alte)
          foreach(
$subarray as $element)
            
$zwischenlager[] = array_merge($alte,array($element));
      
$result $zwischenlager;
    }
    return 
$result;
  }

/**
 * Prüft ob der Index gültig ist
 *
 * Diese Methode ist Teil der ArrayAccess Schnittstelle
 *
 * @param index Index der gewünschten Vertauschung
 * @return boolean verfügbar
 */
  
public function offsetExists($index)
  {
    return 
$index >= && $index $this->count;
  }

/**
 * Prüft ob der interne Zeiger gültig ist
 *
 * Diese Methode ist Teil der Iterator Schnittstelle
 *
 * @return boolean verfügbar
 */
  
public function valid()
  {
    return 
$this->offsetExists($this->pos);
  }

/**
 * Prüft ob der interne Zeiger gültig ist
 *
 * Diese Methode ist Teil der Countable Schnittstelle
 *
 * @return integer Anzahl möglicher Vertauschungen
 */
  
public function count()
  {
    return 
$this->count;
  }

/**
 * Setzt den interne Zeiger wieder aud Anfang
 *
 * Diese Methode ist Teil der Iterator Schnittstelle
 *
 * @return void Keine Rückgabe
 */
  
public function rewind()
  {
    
$this->pos 0;
  }
  
/**
 * Holt die Vertauschung auf die der interne Zeiger verweist
 *
 * Diese Methode ist Teil der Iterator Schnittstelle
 *
 * @return array Aktuelle Vertauschung
 */
  
public function current()
  {
    return 
$this[$this->pos];
  }

/**
 * Holt den internen Zeiger, also den Array Index
 *
 * Diese Methode ist Teil der Iterator Schnittstelle
 *
 * @return array Aktuelle Vertauschung
 */
  
public function key()
  {
    return 
$this->pos;
  }

/**
 * Setzt den interne Zeiger eine Position weiter
 *
 * Diese Methode ist Teil der Iterator Schnittstelle
 *
 * @return void Keine Rückgabe
 */
  
public function next()
  {
    
$this->pos++;
  }

/**
 * nicht implementiert
 *
 * Diese Methode ist Teil der ArrayAccess Schnittstelle
 *
 * @return void Keine Rückgabe
 */
  
public function offsetSet($index,$newval)
  {
    throw new \
Exception('Setter not implemented',5);
  }

/**
 * nicht implementiert
 *
 * Diese Methode ist Teil der ArrayAccess Schnittstelle
 *
 * @return void Keine Rückgabe
 */
  
public function offsetUnset($index)
  {
    throw new \
Exception('Unsetter not implemented',6);
  }
}