PHP关联数组仅包含键名

3

是否可以声明一个数组元素键而不定义它的值(就像非数组变量一样)?这样,如果您有一个布尔类型的关联数组,您只需要检查键是否存在,而不是分配一个布尔值。但您仍然可以享受不必在检查键是否存在时迭代数组的优势。

这将是一项节省空间的措施。似乎“null”会被分配空间。


2
这听起来很像过早优化。这真的必要吗?你有数据证明它是必要的吗? - user788472
1
我不是说这是必要的,但如果可以的话,我想节省空间。 - user528451
这有点反向。为什么不只是将“键”作为字符串值存储在数组中并使用array_search()呢?值的不存在等于布尔值未设置。 - Michael Berkowski
1
@Michael Berkowski 你会遍历数组而不是关联数组吗?还是两种情况都会发生迭代? - user528451
1
@Nathan Bouscal 我听说过他,但这并不是过早的。我们已经让它工作了,只是想让它更好地工作。 - user528451
显示剩余3条评论
4个回答

2

如果您不想像在关联数组中那样拥有字典结构,而只是想要一组值,就像这样:

$array = ('red', 'green', 'blue');

要检查一个键(项)是否存在,只需使用in_array()

if(in_array('red', $array)) {
   // -> found
}

然而,你需要注意的是在这种情况下php会内部创建数字索引。


另一种方法是将所有值都赋值为TRUE。这样至少会占用更少的内存。就像这样:

$array (
    'red' => TRUE,
    'green' => TRUE,
    'blue' => TRUE
);

使用 isset() 检查变量是否存在,格式如下:

if(isset($array['red'])) {
    // -> found
}
注意:我不建议您使用NULL作为值。这是因为在这种情况下,您无法使用isset(),因为如果键的值为NULL,则isset将返回false。在这种情况下,您必须使用array_key_exists(),但它比isset()慢得多。
结论:就处理器和内存消耗而言,我建议您使用PHP中的第二个建议。内存消耗应该与数字数组相同,但搜索操作已经优化。

你说这些条目没有键,这是不正确的。 - Marcin Orlowski
确实,它们具有数字(或更好的索引),但这是使用PHP的方法。 - hek2mgl
@WebnetMobile 你现在开心了吗? - hek2mgl
从空间角度来看,这样做是不错的,但从处理器的角度来看,你必须遍历该集合? - user528451
就处理器和内存而言,我建议您使用第二个建议,将TRUE作为值。 - hek2mgl

2

数组元素总是具有键和值,但如果您不关心值(即空字符串),则可以将任何内容作为值放入其中。在您的情况下,您应该只向数组中添加这些具有值的键,例如true。然后,当您查找它时无法找到它时,您可以假设它为假。但总的来说,您正在做错事。这样做不仅无法节省代码,还会使代码难以阅读和维护。请不要这样做。


1
如果我理解正确,您计划使用这样的关联数组:
key      value
"bool1"  ""
"bool2"  ""
"bool3"  ""

如果键存在,则布尔值为“true”。 为什么不使用普通数组,就像这样?:
key   value
1     "bool1"
2     "bool2"
3     "bool3"

如果该值存在,则布尔值为“true”。

然后,检查值是否存在需要O(n)的时间,相比之下,键查找只需要O(1)的时间。 - user2340939

-1

是的,这是可能的。您还可以使用array_key_exists来检查这些值。PHP将变量名称的哈希映射与实际数据存储分开(如果您感兴趣,请在Google上搜索zval)。话虽如此,数组在每个元素上还需要有一个关联的“bucket”结构,这取决于您的操作系统和编译选项,可以高达96字节/每个。顺便说一句,zvals每个也高达48字节。

然而,我认为您不太可能从这种方案中获得太多价值,但纯粹从假设的角度来看,您可以存储空值。

<?php

$foo = array('a' => null, 'b' => null);

if (array_key_exists('a', $foo))
    echo 'a';

然而,与初始化为布尔值相比,这并不会节省任何内存。这将使您执行isset,这比调用array_key_exists函数更快。

<?php
$foo = array('a' => true, 'b' => true);

if (isset($foo['a']))
   echo 'a';

不可能没有键的数组值。您不能使用自己的键,但在这种情况下,条目将被分配自己的唯一键。 - Marcin Orlowski
问题是询问您是否可以拥有一个没有值的键,而不是反过来。您肯定可以拥有一个被赋予 null 值的键。 - gview
我运行了一个测试程序,显然 null 占用了 96 字节的空间。 - user528451
对于数组,为每个元素分配一个变量存储单元(zval)。这仅是任何变量所需的php开销。如果该变量被类型化,则会有适合变量类型的额外存储开销。因此,总是会有一些开销。另外,就其价值而言,我完全同意这是应该避免的微观优化,但深入了解php的内部原理也有助于更好地理解它。 - gview
此外,PHP 中的数组在灵活性方面非常强大,但也很昂贵。每个数组元素都需要一个 PHP 的“桶”结构,假设您创建了一个只有一个元素的数组,则可能需要占用您提到的 96 字节。 - gview

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接