2009-11-25 1 views
3

Я хочу создать класс-оболочку, который позволит использовать дубликаты ключей, в то время как хэш-настройки по умолчанию не позволяют. Класс должен использовать механизм перегрузки элементов, введенный в php5, поэтому он будет имитировать все стандартные хэши поведения. Например, я хочу, чтобы чего-л, какКак создать структуру данных с ключевыми дубликатами в php вместо хэша по умолчанию?

$var => obj(:values_arr -> array(
     obj(:key -> 'mykey', :value -> 'val1'), 
     obj(:key -> 'mykey', :value -> 'val2') 
    ) 
) 

Если я хочу, чтобы получить $ вар [ «MYKEY»], он должен вернуть массив («val1», «val2»), но если я хочу продлить OBJ с новым «MyKey» => «значение» пары, я бы назвал

$val['mykey'][] = 'value' 

Основная идея заключается в том, что поведение хэш сохранилась и после того, как попытка присвоить значение, используя существующий ключ, он не будет перезаписана, но прилагается к списку.

Как бы вы имитировали другие структуры данных в php5 (до 5.3)? Существуют ли какие-либо известные решения или примеры, которые вы хотите поделиться?

ответ

2

как этот

class MultiMap 
{ 
    protected $map = array(); 

    function __set($key, $val) { 
     if(!isset($this->map[$key])) 
      return $this->map[$key] = $val; 
     if(!is_array($this->map[$key])) 
      $this->map[$key] = array($this->map[$key]); 
     $this->map[$key][] = $val; 
    } 
    function __get($key) { 
     return $this->map[$key]; 
    } 
} 

$m = new MultiMap; 
$m->foo = 1; 
$m->foo = 2; 
$m->bar = 'zzz'; 
print_r($m->foo); 
print_r($m->bar); 

, но в целом идея выглядит немного странно для меня. Можете ли вы объяснить, зачем вам это нужно?

это не для меня ясно, почему вам нужно операторов в качестве ключей в вашей AST , возможно, структура, как это было бы более удобно

('op' => 'AND', 'args' => [ 
     (op => AND, args => [ 
      (op => atom, value => word1), 
      (op => atom, value => word2), 
     ]), 
     (op => AND, args => [ 
      (op => atom, value => word3), 
      (op => atom, value => word4), 
     ]) 
    ]) 
+0

мне это нужно для абстрактного синтаксиса дерева строитель. Например, я мог бы иметь выражение ((word1 AND word2) AND (word3 AND word4)). Я буду преобразован в массив 'array ('AND' => array ('AND' => array ('word1', 'word2'), 'AND' => array ('word3', 'word4'));' – altern

0

Вы можете достичь синтаксиса массива

$val['mykey'] = 'value'; 

с ArrayAccess

class MultiHash implements ArrayAccess, IteratorAggregate 
{ 
    protected $data; 

    public function offsetGet($offset) 
    { 
     return $this->data[$offset]; 
    } 
    public function offsetSet($offset, $value) 
    { 
     if ($offset === null) { // $a[] = ... 
      $this->data[] = array($value); 
     } else { 
      $this->data[$offset][] = $value; 
     } 
    } 
    public function offsetExists($offset) 
    { 
     return isset($this->data[$offset]); 
    } 
    public function offsetUnset($offset) 
    { 
     unset($this->data[$offset]); 
    } 

    public function getIterator() 
    { 
     $it = new AppendIterator(); 
     foreach ($this->data as $key => $values) { 
      $it->append(new ConstantKeyArrayIterator($values, 0, $key)); 
     } 
     return $it; 
    } 
} 

class ConstantKeyArrayIterator extends ArrayIterator 
{ 
    protected $key; 

    public function __construct($array = array(), $flags = 0, $key = 0) 
    { 
     parent::__construct($array,$flags); 
     $this->key = $key; 
    } 
    public function key() 
    { 
     return parent::key() === null ? null : $this->key; 
    } 
} 

I als o реализовано IteratorAggregate, чтобы разрешить итерацию по всем отдельным элементам.

Код проверки

$test = new MultiHash(); 
$test[] = 'foo'; 
$test[] = 'bar'; 
$test['mykey'] = 'val1'; 
$test['mykey'] = 'val2'; 
$test['mykey2'] = 'val3'; 

echo "mykey: "; 
var_dump($test['mykey']); 

echo "mykey2: "; 
var_dump($test['mykey2']); 

echo "iterate:\n"; 
foreach ($test as $key => $value) { 
    echo "$key : $value \n"; 
} 

Test Output

mykey: array(2) { 
    [0]=> 
    string(4) "val1" 
    [1]=> 
    string(4) "val2" 
} 
mykey2: array(1) { 
    [0]=> 
    string(4) "val3" 
} 
iterate: 
0 : foo 
1 : bar 
mykey : val1 
mykey : val2 
mykey2 : val3 

 Смежные вопросы

  • Нет связанных вопросов^_^