我正在查看 PHP 手册,但是我没有看到大多数编程语言都有的数据结构部分,例如列表和集合。我是瞎了还是 PHP 没有内置这样的东西?
我正在查看 PHP 手册,但是我没有看到大多数编程语言都有的数据结构部分,例如列表和集合。我是瞎了还是 PHP 没有内置这样的东西?
PHP中唯一的本地数据结构是数组。幸运的是,数组非常灵活,也可以用作哈希表。
不过,PHP也有SPL这个东西,它有些类似于C++ STL。
PHP提供数据结构通过标准 PHP 库 (SPL) 基本扩展,PHP 5.0.0 默认编译安装。
可用于 PHP 5 >= 5.3.0 的数据结构包括:
双向链表 (DLL) 是一组节点互相链接的链表,每个节点都有两个方向。当底层结构是 DLL 时,迭代器操作、访问两端、添加或移除节点的成本为 O(1)。因此,它为栈和队列提供了一个不错的实现。
堆是类似于树状结构的结构,遵循堆属性:每个节点都大于或等于其子节点,使用实现的 compare 方法进行比较(对于堆来说该方法是全局的)。
数组是以连续方式存储数据的结构,可以通过索引访问。不要将它们与 PHP 数组混淆:实际上,PHP 数组被实现为有序哈希表。
映射是一种存储键-值对的数据结构。PHP数组可以被看作是从整数/字符串到值的映射。SPL提供了一个从对象到数据的映射。这个映射也可以用作对象集。
关联数组可用于大多数基本数据结构哈希表、队列、栈。但如果您需要像树或堆这样的内容,我认为它们不会默认存在,但我确定有免费的库可以使用。
要让数组模拟栈,请使用array_push()
添加元素和array_pop()
弹出元素。
要让数组模拟队列,请使用array_push()
将元素入队和array_shift()
将元素出队。
PHP中的关联数组默认为哈希表,它们允许使用字符串作为索引,因此以下操作按预期工作:
$array['key'] = 'value';
最后,你可以使用一个数组来模拟二叉树,但这样可能会浪费一些空间。如果你知道你的树很小,那么这种方法就很有用了。使用线性数组,你可以说对于任何索引(i),你将它的左子节点放在索引(2i+1)处,右子节点放在索引(2i+2)处。
所有这些方法都在这篇文章中得到了很好地阐述,该文章介绍如何使用JavaScript数组模拟更高级别的数据结构。
PHP有数组,实际上是关联数组,也可以用作集合。与许多解释型语言一样,PHP在一个包中提供了所有这些功能,而不是提供不同的显式数据类型。
例如:
$lst = array(1, 2, 3);
$hsh = array(1 => "This", 2 => "is a", 3 => "test");
PHP的数组既可以作为列表,也可以作为字典。
(PHP的array可以同时作为list和dictionary。)$myArray = array("Apples", "Oranges", "Pears");
$myScalar = $myArray[0] // == "Apples"
或者将其用作关联数组:
$myArray = array("a"=>"Apples", "b"=>"Oranges", "c"=>"Pears");
$myScalar = $myArray["a"] // == "Apples"
如果您感觉PHP没有特定类型的数据结构,您可以随时创建自己的数据结构。例如,这里有一个简单的基于数组的Set数据结构。
class ArraySet
{
/** Elements in this set */
private $elements;
/** the number of elements in this set */
private $size = 0;
/**
* Constructs this set.
*/
public function ArraySet() {
$this->elements = array();
}
/**
* Adds the specified element to this set if
* it is not already present.
*
* @param any $element
*
* @returns true if the specified element was
* added to this set.
*/
public function add($element) {
if (! in_array($element, $this->elements)) {
$this->elements[] = $element;
$this->size++;
return true;
}
return false;
}
/**
* Adds all of the elements in the specified
* collection to this set if they're not already present.
*
* @param array $collection
*
* @returns true if any of the elements in the
* specified collection where added to this set.
*/
public function addAll($collection) {
$changed = false;
foreach ($collection as $element) {
if ($this->add($element)) {
$changed = true;
}
}
return $changed;
}
/**
* Removes all the elements from this set.
*/
public function clear() {
$this->elements = array();
$this->size = 0;
}
/**
* Checks if this set contains the specified element.
*
* @param any $element
*
* @returns true if this set contains the specified
* element.
*/
public function contains($element) {
return in_array($element, $this->elements);
}
/**
* Checks if this set contains all the specified
* element.
*
* @param array $collection
*
* @returns true if this set contains all the specified
* element.
*/
public function containsAll($collection) {
foreach ($collection as $element) {
if (! in_array($element, $this->elements)) {
return false;
}
}
return true;
}
/**
* Checks if this set contains elements.
*
* @returns true if this set contains no elements.
*/
public function isEmpty() {
return count($this->elements) <= 0;
}
/**
* Get's an iterator over the elements in this set.
*
* @returns an iterator over the elements in this set.
*/
public function iterator() {
return new SimpleIterator($this->elements);
}
/**
* Removes the specified element from this set.
*
* @param any $element
*
* @returns true if the specified element is removed.
*/
public function remove($element) {
if (! in_array($element, $this->elements)) return false;
foreach ($this->elements as $k => $v) {
if ($element == $v) {
unset($this->elements[$k]);
$this->size--;
return true;
}
}
}
/**
* Removes all the specified elements from this set.
*
* @param array $collection
*
* @returns true if all the specified elemensts
* are removed from this set.
*/
public function removeAll($collection) {
$changed = false;
foreach ($collection as $element) {
if ($this->remove($element)) {
$changed = true;
}
}
return $changed;
}
/**
* Retains the elements in this set that are
* in the specified collection. If the specified
* collection is also a set, this method effectively
* modifies this set into the intersection of
* this set and the specified collection.
*
* @param array $collection
*
* @returns true if this set changed as a result
* of the specified collection.
*/
public function retainAll($collection) {
$changed = false;
foreach ($this->elements as $k => $v) {
if (! in_array($v, $collection)) {
unset($this->elements[$k]);
$this->size--;
$changed = true;
}
}
return $changed;
}
/**
* Returns the number of elements in this set.
*
* @returns the number of elements in this set.
*/
public function size() {
return $this->size;
}
/**
* Returns an array that contains all the
* elements in this set.
*
* @returns an array that contains all the
* elements in this set.
*/
public function toArray() {
$elements = $this->elements;
return $elements;
}
}
$foo = array(
'bar' => array(1,'two',3),
'baz' => explode(" ", "Some nice words")
);
如果你需要对数组进行映射、筛选、遍历等操作,或者进行转换、翻转等操作,那么有大量的数组函数可供使用。