PHP依存クラス

クラス:

class deps{

  var $items;

  function add($item, $deps = array()){
    $this->items[$item] = $deps;
  }


}

依存関係($ deps)を考慮して$ items配列を生成するにはどうすればよいですか?

例えば:

$deps = new deps;

$deps->add('item2', array('item1'));           //<- depends on item1
$deps->add('item1', array());                  //<- no dependency
$deps->add('item3', array('item1', 'item5'));  //<- depends on item1 and item5
$deps->add('A',     array('item3'));           //<- on item3
$deps->add('C',     array('item2', 'item1'));  //......

順序付き配列は次のようになります。

item1
item2
C

存在しなかった1つ以上の依存関係を必要とする項目を持つ2番目の配列:

item3       
A
0
DICとは何ですか?どのように私は "ピンプル"私が欲しいものを行うことができますか?
追加された 著者 Alex,
これがDICの場合は、 github.com/fabpot/Pimple components.symfony-project.org/dependency-injection/- もしそうでなければDICはあなたのシナリオを明確にすることを検討します。
追加された 著者 Gordon,
DICは依存性注入容器を意味する。 DICの後にいない場合は、達成しようとしていることを明確にしてください。ここでユースケースは何ですか?あなたのアプリケーションでクラスdepsをどのように使用しますか?責任は何ですか?あなたのコード例は私には奇妙に見えますが、目的を理解することができないため、質問に答えにくいです。
追加された 著者 Gordon,
私は array_walk()関数はあなたが必要とするものだと思います。
追加された 著者 Minras,

3 答え

何かのようなもの:

class deps{
  protected $items = array();

  public function add($item, array $deps = array()){
    $this->items[$item] = $deps;
  }

  protected function checkDependencies($item) {
    if (!isset($this->items[$item])) {
      return false;
    }

    foreach ($this->items[$item] as $dep) {
      if (!$this->checkDependencies($dep)) {
        return false;
      }
    }

    return true;
  }

  public function getResolved() {
    $result = array();

    foreach ($this->items as $item => $deps) {
      if ($this->checkDependencies($item)) {
        $result[] = $item;
      }
    }

    return $result;
  }

  public function getUnresolved() {
    $result = array();

    foreach ($this->items as $item => $deps) {
      if (!$this->checkDependencies($item)) {
        $result[] = $item;
      }
    }

    return $result;
  }
}

$deps = new deps;

$deps->add('item2', array('item1'));           //<- depends on item1
$deps->add('item1', array());                  //<- no dependency
$deps->add('item3', array('item1', 'item5'));  //<- depends on item1 and item5
$deps->add('A',     array('item3'));           //<- on item3
$deps->add('C',     array('item2', 'item1'));  //......

print_r($deps->getResolved());
/*
Array
(
    [0] => item2
    [1] => item1
    [2] => C
)
*/

print_r($deps->getUnresolved());
/*
Array
(
    [0] => item3
    [1] => A
)
*/

http://codepad.org/fSwJjyz5

2
追加された
+1 - しかし、 getResolved()のループに else 条件を追加し、 checkDependencies()を自分の配列に追加し、 array( 'valid' => $ valid、 'invalid' => $ invalid) (OPは両方の配列が必要でした)。
追加された 著者 FtDRbwLXw6,
ああ..私はあなたのコードの残りの部分を見ず、 getResolved()メソッドの後で停止したと考えました。私の間違い。 :-)
追加された 著者 FtDRbwLXw6,
ありがとう!私はこれを使用して終了しました: johnkleijn.nl/2010/Topological-sorting -of-JavaScriptファイル
追加された 著者 Alex,
@drrcknlsnええ、私は結果の形式についてはわからなかったので、私はそれぞれの場合に1つずつ、2つの方法を使用しました。
追加された 著者 Yoshi,

ビットが乱雑ですが、正しいロード順(1,2、C)を返し、未解決です。

<?php

class Dependencies
{
    private $_items;
    private $_dependencies;

    public function add($item, $dependencies = array())
    {
        $this->_items[$item] = (count($dependencies) > 0) ? $dependencies : null;

        foreach($dependencies as $dependency)
        {
            $this->_dependencies[$dependency][] = $item;
        }
    }

    public function get_load_order()
    {
        $load_order = array();
        $seen       = array();

        foreach($this->_items as $item => $dependencies)
        {
            $tmp = $this->get_dependents($item, $seen);

            if($tmp[2] === false)
            {
                $load_order = array_merge($load_order, $tmp[0]);
                $seen       = $tmp[1];
            }
        }

        return $load_order;
    }

    public function get_failed_items()
    {
        $failed = array();
        $seen   = array();

        foreach($this->_items as $item => $dependencies)
        {
            $tmp = $this->get_dependents($item, $seen);

            if($tmp[2] !== false)
            {
                $failed[] = $item;
                continue;
            }

            $seen = $tmp[1];
        }

        return $failed;
    }

    private function get_dependents($item, $seen = array())
    {
        if(array_key_exists($item, $seen))
        {
            return array(array(), $seen, false);
        }

        if($this->item_exists($item))
        {
            $order          = array();
            $failed         = array();
            $seen[$item]    = true;

            if($this->has_dependents($item))
            {
                foreach($this->_items[$item] as $dependency)
                {
                    $tmp = $this->get_dependents($dependency, $seen);

                    $order  = array_merge($tmp[0], $order);
                    $seen   = $tmp[1];

                    if($tmp[2] !== false)
                    {
                        $failed = array_merge($tmp[2], $failed);
                    }
                }
            }

            $order[]    = $item;
            $failed     = (count($failed) > 0) ? $failed : false;

            return array($order, $seen, $failed);
        }

        return array(array(), array(), array($item));
    }

    private function item_exists($item)
    {
        if(array_key_exists($item, $this->_items))
        {
            return true;
        }

        return false;
    }

    private function has_dependents($item)
    {
        if($this->item_exists($item) AND is_array($this->_items[$item]))
        {
            return true;
        }

        return false;
    }
}

呼び出される:

<?php

$deps = new Dependencies();

$deps->add('item2', array('item1'));           //<- depends on item1
$deps->add('item1');                           //<- no dependency
$deps->add('item3', array('item1', 'item5'));  //<- depends on item1 and item5
$deps->add('A',     array('item3'));           //<- on item3
$deps->add('C',     array('item2', 'item1'));  //......

$load_order     = $deps->get_load_order();
$failed_items   = $deps->get_failed_items();

echo '
';
echo 'Loaded: ';
print_r($load_order);
echo 'Failed: ';
print_r($failed_items);
echo '
';

プロデュース:

Loaded: Array
(
    [0] => item1
    [1] => item2
    [2] => C
)
Failed: Array
(
    [0] => item3
    [1] => A
)
2
追加された

あなたが提供したデータで、これは依存関係を注文するトリックでした。

function returnOrderedDependencies()
{
    $temporary = $this->items;
    $dependencies = array();

    $isChanged = true;
    while ($isChanged == true) {
        $isChanged = false;
       //Step 1. Search for items without dependencies
        foreach ($temporary as $item => $deps) {
            if (empty($deps)) {
                array_push($dependencies, $item);
                unset($temporary[$item]);
            }
        }
           //Step 2. Remove resolved items from dependencies
        foreach ($temporary as $item => $deps) {
            foreach ($deps as $key => $value) {
                if (in_array($value, $dependencies)) {
                    $isChanged = true;
                    unset($temporary[$item][$key]);
                }
            }
        }
    }
    return $dependencies;
}

$ temporaryに残っている項目は未解決の依存関係です。あなたのデータは期待通りに返されましたが、これは偶然であると思います。

私は未解決の依存関係をどのように秩序づけるか、おそらくどれだけ多くの依存関係がこれらの項目に対して解決されていないのかについては分かりません。

1
追加された
PHP - 日本のコミュニティ [ja]
PHP - 日本のコミュニティ [ja]
4 参加者の

このグループではPHPについて話します。 パートナー:kotaeta.com