デフォルトのハッシュの代わりにPHPで重要な複製を使用してデータ構造を作成する方法は?
質問
キーが複製できるようにするラッパークラスを作成したいのですが、デフォルトのハッシュでは許可されません。クラスは、PHP5で導入されたメンバーオーバーロードメカニズムを使用する必要があるため、標準ハッシュが持っているすべての動作を模倣します。たとえば、SMTHが好きになりたいです
$var => obj( :values_arr -> array(
obj(:key -> 'mykey', :value -> 'val1'),
obj(:key -> 'mykey', :value -> 'val2')
)
)
$ var ['mykey']を取得したい場合は、配列( 'val1'、 'val2')を返す必要がありますが、new 'mykey' => 'value'ペアでobjを拡張したい場合は、電話します
$val['mykey'][] = 'value'
主な考え方は、ハッシュの動作が保存され、既存のキーを使用することに値を割り当てようとすると、上書きされることはありませんが、リストに追加されるということです。
PHP5の他のデータ構造をどのように模倣しますか(5.3以前)?共有したい既知のソリューションや例はありますか?
解決
このような
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),
])
])
他のヒント
配列構文を実現できます
$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;
}
}
私も実装しました 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";
}
テスト出力
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
所属していません StackOverflow