2

我正在将一段 Java 代码移植到 PHP 中,该代码使用了大量的双向地图(Guava 的 BiMap)。类似 Java 的地图由 PHP 数组或SplObjectStorage提供,但是否有可用的库 PHP 双向地图?

4

2 回答 2

2

此类应提供双向地图的大多数需求:

class BiMap
{

    private $KtoV, $VtoK;

    public function __constructor()
    {
        $this->KtoV = []; // for version < 5.4.0, syntax must be: $this->KtoV = array();
        $this->VtoK = [];
    }

    public function getKey($v)
    {
        if($this->hasValue($v))
        {
            return $this->VtoK[$v];
        }
        else
        {
            return null;
        }
    }

    public function getAllKeys()
    {
        if($this->KtoV)
        {
            return array_keys($this->KtoV);
        }
        else
        {
            return $this->KtoV;
        }
    }

    public function getValue($k)
    {
        if($this->hasKey($k))
        {
            return $this->KtoV[$k];
        }
        else
        {
            return null;
        }
    }

    public function getAllValues()
    {
        if($this->VtoK)
        {
            return array_keys($this->VtoK);
        }
        else
        {
            return $this->VtoK;
        }
    }

    public function hasKey($k)
    {
        return isset($this->KtoV[$k]);
    }

    public function hasValue($v)
    {
        return isset($this->VtoK[$v]);
    }

    public function put($k, $v)
    {
        if($this->hasKey($k))
        {
            $this->removeKey($k);
        }
        if($this->hasValue($v))
        {
            $this->removeValue($v);
        }
        $this->KtoV[$k] = $v;
        $this->VtoK[$v] = $k;
    }

    public function putAll($array)
    {
        foreach($array as $k => $v)
        {
            $this->put($k, $v);
        }
    }

    public function removeKey($k)
    {
        if($this->hasKey($k))
        {
            unset($this->VtoK[$this->KtoV[$k]]);
            $v = $this->KtoV[$k];
            unset($this->KtoV[$k]);
            return $v;
        }
        else
        {
            return null;
        }
    }

    public function removeValue($v)
    {
        if($this->hasValue($v))
        {
            unset($this->KtoV[$this->VtoK[$v]]);
            $k = $this->VtoK[$v];
            unset($this->VtoK[$v]);
            return $k;
        }
        else
        {
            return null;
        }
    }

}

但是,如果您需要对键/值和/或对象/数组检查进行空值检查,则应在函数体中给出类似于以下代码行的处理,并在hasKey($k),hasValue($v)put($k, $v)方法中适当地调用:

    if($item === null)
    {
        throw new Exception('null as BiMap key / value is invalid.');
    }
    if(is_object($item) || is_array($item))
    {
        throw new Exception('Object / Array as BiMap key / value is invalid.');
    }
于 2013-10-08T10:53:18.610 回答
0

一旦将值放入2个数组中,我就这样做了。如果 keySet() 和 valueSet() 是分离的,你甚至可以使用一个值。例子:

$mapKtoV = array();
$mapVtoK = array();

function putInMap ($key,$value)
{
    $mapKtoV[$key] = $value;
    $mapVtoK[$value] = $key;
}

当然你也可以把它们放到一个类中。

您是否还认为这种解决方案看起来很狡猾和有异味?是的,没错,欢迎来到 PHP 的世界,这个世界通常以糟糕的代码设计为主。如果您真的在寻找一个好的解决方案,您实际上应该将源代码从 PHP 移植到 Java ;)

希望能帮助到你。

于 2013-07-04T07:42:50.930 回答