2013-08-06 35 views
0

我正在學習模式並在此時玩弄一個示例,但我似乎無法使removeUnit方法按預期工作。下面的代碼:從複合/陣列(複合圖案)中刪除元素

<?php 
abstract class Unit 
{ 
    abstract function strength(); 
    public function getComposite() 
    { 
     return false; 
    } 
} 

/* 
* composite/group class 
*/ 
abstract class Composite extends Unit 
{ 
    private $_units = array(); 

    // check if class is a composite or not 
    public function getComposite() 
    { 
     return true; 
    } 

    public function getUnits() 
    { 
     return $this->_units; 
    } 

    // add a unit to the group 
    public function addUnit(Unit $unit) 
    { 
     if(in_array($unit, $this->_units, true)) { 
      Throw new exception("Sorry, the following unit is already in the army"); 
     } else { 
      array_push($this->_units, $unit); 
     } 
    } 

    //remove a unit from the group 
    public function removeUnit(Unit $unit) 
    { 
     if(! in_array($unit, $this->_units, true)) { 
      Throw new Exception("Hm, it looks like this unit is not a part of this army."); 
     } else { 
      $key = array_search($unit, $this->_units); 
      array_splice($this->_units, $key); 
     } 
    } 
} 

class Army extends Composite 
{ 
    public function strength() 
    { 
     $units = $this->getUnits(); 
     $armyStrength = 0; 
     foreach($units as $unit) { 
      $armyStrength += $unit->strength(); 
     } 
     return $armyStrength; 
    } 
} 

class Riffle extends Unit 
{ 
    public function strength() 
    { 
     return 5; 
    } 
} 

class Rocket extends Unit 
{ 
    public function strength() 
    { 
     return 15; 
    } 
} 

$riffle1 = new Riffle(); 
$riffle2 = new Riffle(); 
$riffle3 = new Riffle(); 

$rocket1 = new Rocket(); 
$rocket2 = new Rocket(); 
$rocket3 = new Rocket(); 

$squad = new Army(); 

$squad->addUnit($riffle1); 
$squad->addUnit($riffle2); 
$squad->addUnit($rocket1); 
$squad->removeUnit($riffle2); 
echo $squad->strength(); 

的問題是在這裏:

//remove a unit from the group 
public function removeUnit(Unit $unit) 
{ 
    if(! in_array($unit, $this->_units, true)) { 
     Throw new Exception("Hm, it looks like this unit is not a part of this army."); 
    } else { 
     $key = array_search($unit, $this->_units); 
     array_splice($this->_units, $key); 
    } 
} 

如果我刪除recket1的一切工作正常,但如果我嘗試刪除riffle1或2我的力氣返回0。這是什麼問題這裏?有沒有更好的方式從數組中刪除元素?

回答

1

您的array_splice調用是錯誤的,因爲省略參數$length將刪除從該點到數組末尾的所有內容。它應該是:

array_splice($this->_units, $key, 1); 

這就是說,我不知道爲什麼你懶得擺在首位,以保護數字指標 - 使用unset($this->_units[$key])也將這樣的伎倆沒有任何明顯的副作用。

最後,獨立做in_arrayarray_search毫無意義。你可以重寫這樣的代碼:

$key = array_search($unit, $this->_units); 
if ($key === false) { 
    // exception 
} 

array_splice($this->_units, $key, 1); 
+0

有道理,這個作品完美,謝謝。我甚至沒有想過只使用unset() – haosmark

+0

@haosmark:你也使用'array_push'而不是'$ arr [] = $ newItem' - 我個人從未使用'array_push'。我能想到的唯一用途就是把它當作回調函數,你不能用特殊的數組語法來完成。 – Jon