PageRenderTime 47ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/yii/framework/collections/CList.php

http://github.com/eryx/php-framework-benchmark
PHP | 342 lines | 167 code | 23 blank | 152 comment | 31 complexity | 94bb4ed0b3601ed25d647603b3bd9627 MD5 | raw file
Possible License(s): MIT, BSD-3-Clause, Apache-2.0, LGPL-2.1, LGPL-3.0, BSD-2-Clause
  1. <?php
  2. /**
  3. * This file contains classes implementing list feature.
  4. *
  5. * @author Qiang Xue <qiang.xue@gmail.com>
  6. * @link http://www.yiiframework.com/
  7. * @copyright Copyright &copy; 2008-2011 Yii Software LLC
  8. * @license http://www.yiiframework.com/license/
  9. */
  10. /**
  11. * CList implements an integer-indexed collection class.
  12. *
  13. * You can access, append, insert, remove an item by using
  14. * {@link itemAt}, {@link add}, {@link insertAt}, {@link remove}, and {@link removeAt}.
  15. * To get the number of the items in the list, use {@link getCount}.
  16. * CList can also be used like a regular array as follows,
  17. * <pre>
  18. * $list[]=$item; // append at the end
  19. * $list[$index]=$item; // $index must be between 0 and $list->Count
  20. * unset($list[$index]); // remove the item at $index
  21. * if(isset($list[$index])) // if the list has an item at $index
  22. * foreach($list as $index=>$item) // traverse each item in the list
  23. * $n=count($list); // returns the number of items in the list
  24. * </pre>
  25. *
  26. * To extend CList by doing additional operations with each addition or removal
  27. * operation (e.g. performing type check), override {@link insertAt()}, and {@link removeAt()}.
  28. *
  29. * @author Qiang Xue <qiang.xue@gmail.com>
  30. * @version $Id: CList.php 3001 2011-02-24 16:42:44Z alexander.makarow $
  31. * @package system.collections
  32. * @since 1.0
  33. */
  34. class CList extends CComponent implements IteratorAggregate,ArrayAccess,Countable
  35. {
  36. /**
  37. * @var array internal data storage
  38. */
  39. private $_d=array();
  40. /**
  41. * @var integer number of items
  42. */
  43. private $_c=0;
  44. /**
  45. * @var boolean whether this list is read-only
  46. */
  47. private $_r=false;
  48. /**
  49. * Constructor.
  50. * Initializes the list with an array or an iterable object.
  51. * @param array $data the initial data. Default is null, meaning no initialization.
  52. * @param boolean $readOnly whether the list is read-only
  53. * @throws CException If data is not null and neither an array nor an iterator.
  54. */
  55. public function __construct($data=null,$readOnly=false)
  56. {
  57. if($data!==null)
  58. $this->copyFrom($data);
  59. $this->setReadOnly($readOnly);
  60. }
  61. /**
  62. * @return boolean whether this list is read-only or not. Defaults to false.
  63. */
  64. public function getReadOnly()
  65. {
  66. return $this->_r;
  67. }
  68. /**
  69. * @param boolean $value whether this list is read-only or not
  70. */
  71. protected function setReadOnly($value)
  72. {
  73. $this->_r=$value;
  74. }
  75. /**
  76. * Returns an iterator for traversing the items in the list.
  77. * This method is required by the interface IteratorAggregate.
  78. * @return Iterator an iterator for traversing the items in the list.
  79. */
  80. public function getIterator()
  81. {
  82. return new CListIterator($this->_d);
  83. }
  84. /**
  85. * Returns the number of items in the list.
  86. * This method is required by Countable interface.
  87. * @return integer number of items in the list.
  88. */
  89. public function count()
  90. {
  91. return $this->getCount();
  92. }
  93. /**
  94. * Returns the number of items in the list.
  95. * @return integer the number of items in the list
  96. */
  97. public function getCount()
  98. {
  99. return $this->_c;
  100. }
  101. /**
  102. * Returns the item at the specified offset.
  103. * This method is exactly the same as {@link offsetGet}.
  104. * @param integer $index the index of the item
  105. * @return mixed the item at the index
  106. * @throws CException if the index is out of the range
  107. */
  108. public function itemAt($index)
  109. {
  110. if(isset($this->_d[$index]))
  111. return $this->_d[$index];
  112. else if($index>=0 && $index<$this->_c) // in case the value is null
  113. return $this->_d[$index];
  114. else
  115. throw new CException(Yii::t('yii','List index "{index}" is out of bound.',
  116. array('{index}'=>$index)));
  117. }
  118. /**
  119. * Appends an item at the end of the list.
  120. * @param mixed $item new item
  121. * @return integer the zero-based index at which the item is added
  122. */
  123. public function add($item)
  124. {
  125. $this->insertAt($this->_c,$item);
  126. return $this->_c-1;
  127. }
  128. /**
  129. * Inserts an item at the specified position.
  130. * Original item at the position and the next items
  131. * will be moved one step towards the end.
  132. * @param integer $index the specified position.
  133. * @param mixed $item new item
  134. * @throws CException If the index specified exceeds the bound or the list is read-only
  135. */
  136. public function insertAt($index,$item)
  137. {
  138. if(!$this->_r)
  139. {
  140. if($index===$this->_c)
  141. $this->_d[$this->_c++]=$item;
  142. else if($index>=0 && $index<$this->_c)
  143. {
  144. array_splice($this->_d,$index,0,array($item));
  145. $this->_c++;
  146. }
  147. else
  148. throw new CException(Yii::t('yii','List index "{index}" is out of bound.',
  149. array('{index}'=>$index)));
  150. }
  151. else
  152. throw new CException(Yii::t('yii','The list is read only.'));
  153. }
  154. /**
  155. * Removes an item from the list.
  156. * The list will first search for the item.
  157. * The first item found will be removed from the list.
  158. * @param mixed $item the item to be removed.
  159. * @return integer the index at which the item is being removed
  160. * @throws CException If the item does not exist
  161. */
  162. public function remove($item)
  163. {
  164. if(($index=$this->indexOf($item))>=0)
  165. {
  166. $this->removeAt($index);
  167. return $index;
  168. }
  169. else
  170. return false;
  171. }
  172. /**
  173. * Removes an item at the specified position.
  174. * @param integer $index the index of the item to be removed.
  175. * @return mixed the removed item.
  176. * @throws CException If the index specified exceeds the bound or the list is read-only
  177. */
  178. public function removeAt($index)
  179. {
  180. if(!$this->_r)
  181. {
  182. if($index>=0 && $index<$this->_c)
  183. {
  184. $this->_c--;
  185. if($index===$this->_c)
  186. return array_pop($this->_d);
  187. else
  188. {
  189. $item=$this->_d[$index];
  190. array_splice($this->_d,$index,1);
  191. return $item;
  192. }
  193. }
  194. else
  195. throw new CException(Yii::t('yii','List index "{index}" is out of bound.',
  196. array('{index}'=>$index)));
  197. }
  198. else
  199. throw new CException(Yii::t('yii','The list is read only.'));
  200. }
  201. /**
  202. * Removes all items in the list.
  203. */
  204. public function clear()
  205. {
  206. for($i=$this->_c-1;$i>=0;--$i)
  207. $this->removeAt($i);
  208. }
  209. /**
  210. * @param mixed $item the item
  211. * @return boolean whether the list contains the item
  212. */
  213. public function contains($item)
  214. {
  215. return $this->indexOf($item)>=0;
  216. }
  217. /**
  218. * @param mixed $item the item
  219. * @return integer the index of the item in the list (0 based), -1 if not found.
  220. */
  221. public function indexOf($item)
  222. {
  223. if(($index=array_search($item,$this->_d,true))!==false)
  224. return $index;
  225. else
  226. return -1;
  227. }
  228. /**
  229. * @return array the list of items in array
  230. */
  231. public function toArray()
  232. {
  233. return $this->_d;
  234. }
  235. /**
  236. * Copies iterable data into the list.
  237. * Note, existing data in the list will be cleared first.
  238. * @param mixed $data the data to be copied from, must be an array or object implementing Traversable
  239. * @throws CException If data is neither an array nor a Traversable.
  240. */
  241. public function copyFrom($data)
  242. {
  243. if(is_array($data) || ($data instanceof Traversable))
  244. {
  245. if($this->_c>0)
  246. $this->clear();
  247. if($data instanceof CList)
  248. $data=$data->_d;
  249. foreach($data as $item)
  250. $this->add($item);
  251. }
  252. else if($data!==null)
  253. throw new CException(Yii::t('yii','List data must be an array or an object implementing Traversable.'));
  254. }
  255. /**
  256. * Merges iterable data into the map.
  257. * New data will be appended to the end of the existing data.
  258. * @param mixed $data the data to be merged with, must be an array or object implementing Traversable
  259. * @throws CException If data is neither an array nor an iterator.
  260. */
  261. public function mergeWith($data)
  262. {
  263. if(is_array($data) || ($data instanceof Traversable))
  264. {
  265. if($data instanceof CList)
  266. $data=$data->_d;
  267. foreach($data as $item)
  268. $this->add($item);
  269. }
  270. else if($data!==null)
  271. throw new CException(Yii::t('yii','List data must be an array or an object implementing Traversable.'));
  272. }
  273. /**
  274. * Returns whether there is an item at the specified offset.
  275. * This method is required by the interface ArrayAccess.
  276. * @param integer $offset the offset to check on
  277. * @return boolean
  278. */
  279. public function offsetExists($offset)
  280. {
  281. return ($offset>=0 && $offset<$this->_c);
  282. }
  283. /**
  284. * Returns the item at the specified offset.
  285. * This method is required by the interface ArrayAccess.
  286. * @param integer $offset the offset to retrieve item.
  287. * @return mixed the item at the offset
  288. * @throws CException if the offset is invalid
  289. */
  290. public function offsetGet($offset)
  291. {
  292. return $this->itemAt($offset);
  293. }
  294. /**
  295. * Sets the item at the specified offset.
  296. * This method is required by the interface ArrayAccess.
  297. * @param integer $offset the offset to set item
  298. * @param mixed $item the item value
  299. */
  300. public function offsetSet($offset,$item)
  301. {
  302. if($offset===null || $offset===$this->_c)
  303. $this->insertAt($this->_c,$item);
  304. else
  305. {
  306. $this->removeAt($offset);
  307. $this->insertAt($offset,$item);
  308. }
  309. }
  310. /**
  311. * Unsets the item at the specified offset.
  312. * This method is required by the interface ArrayAccess.
  313. * @param integer $offset the offset to unset item
  314. */
  315. public function offsetUnset($offset)
  316. {
  317. $this->removeAt($offset);
  318. }
  319. }