PHP有内置数据结构吗?

时间:2008-08-22 13:47:43

标签: php data-structures

我正在查看PHP Manual,我没有看到大多数语言都有的数据结构部分,例如列表和集合。我只是盲目还是PHP没有内置的任何内容?

14 个答案:

答案 0 :(得分:52)

PHP中唯一的本机数据结构是数组。幸运的是,数组非常灵活,也可以用作哈希表。

http://www.php.net/array

但是,SPL是C ++ STL的一种克隆。

http://www.php.net/manual/en/book.spl.php

答案 1 :(得分:28)

PHP通过标准PHP库(SPL)基本扩展提供数据结构,该扩展在PHP 5.0.0中默认可用并编译。

提供的数据结构可以使用PHP 5> = 5.3.0,包括:

双重链接列表

双向链接列表(DLL)是在两个方向上相互链接的节点列表。当底层结构是DLL时,迭代器的操作,对两端的访问,节点的添加或删除都具有O(1)的成本。因此,它为堆栈和队列提供了一个不错的实现。

堆是遵循heap-property的树状结构:每个节点大于或等于其子节点,使用已实现的全局堆比较方法进行比较。

阵列

数组是以连续方式存储数据的结构,可通过索引访问。不要将它们与PHP数组混淆:PHP数组实际上是作为有序哈希表实现的。

地图

地图是包含键值对的数据结构。 PHP数组可以看作是从整数/字符串到值的映射。 SPL提供从对象到数据的映射。此地图也可以用作对象集。

来源:http://php.net/manual/en/spl.datastructures.php

答案 2 :(得分:15)

关联数组可用于大多数基本数据结构哈希表,队列,堆栈。但是如果你想要像树或堆这样的东西,我认为默认情况下它们不存在,但我确信在任何地方都有免费的库。

要让数组模拟堆栈,请使用array_push()添加array_pop()以取消

要让数组模拟队列,请使用array_push()排队并array_shift()出队

关联数组默认为哈希。在PHP中,允许它们将字符串作为索引,以便按预期工作:

$array['key'] = 'value';

最后,您可以使用可能浪费空间的数组来模拟二叉树。如果你知道你将拥有一棵小树,它会很有用。使用线性数组,你说任何索引(i)你把它的左子项放在索引(2i + 1)和右子项索引(2i + 2)。

所有这些方法都在this article中很好地介绍了如何使JavaScript数组模拟更高级别的数据结构。

答案 3 :(得分:8)

虽然这个问题已经有8年了,但我发布了一个答案,因为PHP 7引入了一个名为ds的扩展,提供了专门的数据结构作为数组的替代。

ds

  • 使用Ds\命名空间。
  • 有3个界面,即CollectionSequenceHashable
  • 有8个类,即VectorDequeQueuePriorityQueueMapSetStack,和Pair

有关详细信息,请查看ManualThis blog post也有一些很棒的信息,包括基准测试。

答案 4 :(得分:6)

PHP具有实际上是关联数组的数组,也可以用作集合。与许多解释型语言一样,PHP提供所有这些,而不是提供不同的显式数据类型。

E.g。

$lst = array(1, 2, 3);
$hsh = array(1 => "This", 2 => "is a", 3 => "test");

/编辑:另外,看看in the manual

答案 5 :(得分:6)

PHP的array同时兼作列表和字典。

$myArray = array("Apples", "Oranges", "Pears");
$myScalar = $myArray[0] // == "Apples"

或者将它用作关联数组:

$myArray = array("a"=>"Apples", "b"=>"Oranges", "c"=>"Pears");
$myScalar = $myArray["a"] // == "Apples"

答案 6 :(得分:3)

我认为你可能想要更具体一点,当你说数据结构时,我会想到几个方向......

数组 - 它们当然有很好的文档记录,可用于。(http://us.php.net/manual/en/book.array.php

SQL数据 - 取决于您使用的数据库,但大多数都可用。 (http://us.php.net/manual/en/book.mysql.php

OOP - 可以设计和实现版本对象。 (http://us.php.net/manual/en/language.oop.php)我必须在php网站上搜索OOP才能找到它。

希望有所帮助,对不起,如果没有。

答案 7 :(得分:3)

当然PHP有数据结构。 php中的数组非常灵活。一些例子:

$foo = array(
  'bar' => array(1,'two',3),
  'baz' => explode(" ", "Some nice words")
);

然后你有足够多的数组函数可用于map / filter / walk / etc结构,或转换,翻转,反转等。

答案 8 :(得分:3)

如果您不认为PHP包含特定类型的数据结构,您可以随时创建自己的数据。例如,这是一个由Array支持的简单Set数据结构。

ArraySet:https://github.com/abelperez/collections/blob/master/ArraySet.php

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;   
    }
}

答案 9 :(得分:1)

PHP还可以有一个数组数组,称为“多维数组”或“矩阵”。您可以拥有二维数组,三维数组等。

答案 10 :(得分:0)

对于数据结构的强制需求,请浏览 SPL (PHP扩展)。他们有数据结构,如堆,链表,等等......

PHP没有列表并准确设置数据结构。但是它们可以通过数组(具有n个维度)来实现,它提供具有单个群集的多个数据

$variable = array(
  'one' => array(1,'char',3),
  'two' => explode("single", "Multiple strings"),
  'three' => all(9,'nine',"nine")
);

它们不完全是列表或集合。但阵列可以取代它。因此无需搜索其他数据结构。

答案 11 :(得分:0)

至今天(PHP 7.4),只有本机结构是array。但是从PHP7扩展DS出现了,它包括新的数据结构,并且它们都比其他实现要快得多(包括公认的答案中建议的SPL)。

DS extension - PHP Manual

接口:CollectionHashableSequence

类:VectorDequeMapPairSetStackQueue,{{1 }}

Orginal article about extension

答案 12 :(得分:-1)

是的。

<?php
$my_array = array("Bird","Cat","Cow");

list($a, $b, $c) = $my_array;
echo "I have several animals, a $a, a $b and a $c.";
?>

http://www.w3schools.com/php/func_array_list.asp

答案 13 :(得分:-4)

C语言将允许创建一个结构,然后像字符串(字符/字节)缓冲区一样填充它。一旦填充完成,代码就会通过结构成员访问缓冲区。以这种方式解析结构化(数据库,图像等)文件真的很不错。我不认为你可以用PHP结构做到这一点 - 或者我(希望)是错误的。

好的 - 好的PHP确实有解包和打包 - 功能相同,但不那么优雅。