Yerine varsayılan karma php anahtar çiftleri ile veri yapısını oluşturmak nasıl?

2 Cevap php

Ben varsayılan karma buna izin vermez iken tuşları çiftleri sağlayacak sarıcı sınıf oluşturmak istiyoruz. Sınıf PHP5 tanıtıldı mekanizmasını aşırı yüklenme üyesi kullanmalısınız, bu nedenle tüm davranış standardı karma sahiptir taklit ediyorum. Örneğin, ben gibi smth istiyorum

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

Ben $ var ['mykey'] almak istiyorsanız, bu dizi ('val1', 'val2') döndürmesi gerekir, ama yeni 'mykey' => 'değer' çifti ile obj uzatmak istiyorsanız, ben dediğimiz

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

Ana fikir karma davranışı korundu ve mevcut tuşunu kullanarak değer atamak girişimi sonrasında, yazılmaz olmaz, ancak listeye eklenmiş olmasıdır.

Nasıl (5.3 öncesi) php5 diğer veri yapılarını taklit istiyorsunuz? Paylaşmak istediğiniz herhangi bir bilinen çözümler veya örnekleri var mı?

2 Cevap

böyle

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);

ama bütün fikir bana biraz tuhaf görünüyor. Bunu neden ihtiyaç açıklayabilir misiniz?

it's not clear for me why you need operators as keys in your AST perhaps a structure böyle would be more convenient

   ('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),
        ])
    ])

Sen dizi sözdizimi elde edebilirsiniz

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

ArrayAccess arayüzü ile

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;
    }
}

Ben de IteratorAggregate tüm tek elemanları üzerinde yineleme izin uygulanmıştır.

Test Code

$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