PHP中的foreach在迭代数组时应该遵循什么顺序?

PHP中的foreach在迭代数组时应该遵循什么顺序?,php,arrays,foreach,Php,Arrays,Foreach,我知道PHP数组不是数组,它实际上是一个有序的hashmap,但我仍然不明白为什么要运行以下代码: <?php $teste = []; $teste[2] = 'Test 2'; $teste[1] = 'Test 1'; $teste[3] = 'Test 3'; foreach ($teste as $t) { echo $t; } 结果对我来说毫无意义,难道不应该按如下顺序排列: Test 1 Test 2 Test 3 。因此,在映射中遇到键值对的顺序将主要取决于

我知道PHP数组不是数组,它实际上是一个有序的hashmap,但我仍然不明白为什么要运行以下代码:

<?php

$teste = [];
$teste[2] = 'Test 2';
$teste[1] = 'Test 1';
$teste[3] = 'Test 3';

foreach ($teste as $t) {
    echo $t;
}
结果对我来说毫无意义,难道不应该按如下顺序排列:

Test 1
Test 2
Test 3
。因此,在映射中遇到键值对的顺序将主要取决于它们添加到映射中的顺序。具有严格递增顺序的
0..n-1
索引序列的数组只是一种特例。您可以通过执行以下操作来测试这一点:

$my_arr=array();
$my_arr[3]=“d”;
$my_arr[1]=“b”;
$my_arr[2]=“c”;
$my_arr[0]=“a”;
// #1
echo json_encode($my_arr,json_PRETTY_PRINT)。“\n”;
// #2
ksort($my_arr);
echo json_encode($my_arr,json_PRETTY_PRINT);
#1的输出:

#2的输出:

请注意,
$my_arr
的两个版本之间的唯一区别是键的顺序。按顺序,数组被编码为对象,但按顺序,数组被编码为简单数组


有关PHP数组的更多信息,请查看文档的链接部分。这已经是该语言的一个有据可查的特性。如果您希望键的排序顺序严格递增,请使用上例中所示的
ksort()

项在添加到数组时按顺序排序。但是你可以按它的键对数组进行排序,你会得到预期的顺序:)@DamianDziaduch是的,这也是我意识到的,奇怪的是PHP文档提到它是按顺序排列的,难道文档不应该提到它只是一个映射吗?有趣!在学习PHP7一书中,Antonio Lopez对数组做了如下解释:“在PHP中,我们没有列表和映射;我们有数组。数组是一种实现列表和映射的数据结构。”然后,在为数组设置自己的索引时,您必须说顺序对您来说并不重要。因此,它被视为一个键,而不是一个索引。嗯,这只是一个线索。我希望看到更多的细节。所以我唯一安全的赌注就是在我做foreach之前总是订购一个数组?PHP真是一团糟,在其他任何一种语言中,映射实际上都是有序的。@gtbono它真的一点也不乱。这是一个特性,不是bug。如果您将密钥分配给未初始化的数组,那么您将因未正确初始化而出错。PHP如何知道您的意图是什么?如果必须按特定顺序排列键,则a)按希望键出现的顺序定义键,或b)在定义键后执行排序。例如,您可以将数组初始化为
[1=>null,2=>null,3=>null]
数组填充键(数组(1,2,3),null)
,然后执行赋值。您有多个选项可供选择。若要在此基础上进行扩展:在添加新密钥时未重新排序的密钥还有其他好处。首先,对每个插入进行排序会对性能产生影响。使用
n
键和
O(n logn)
排序算法,我们可以得到
O(n*n logn)
。这是一个不受欢迎的性能打击。即使我们只是简单地插入一个数组,也会得到
O(n*n)
。如果我们在所有插入之后只进行一次排序,那么我们的排序将在
O(n log n)
时间内运行,这比插入时的两个排序选项都好。维护插入顺序还提供了按插入排序将完全消除的功能。在所有情况下,对于那些不关心插入顺序的人来说,排序对性能的影响永远不会进入等式。它们的插入将保留运行时复杂性
O(1)
。在大多数情况下,映射的顺序并不重要,因此丢弃这种额外的排序复杂性可以为大多数开箱即用的用例提供性能优势。对于那些需要排序行为的特殊边缘情况,
ksort()
用于填补空白。对于那些不想记住调用
ksort()
的人,他们可以将赋值包装在一个函数中,该函数在赋值后调用
ksort()
Test 1
Test 2
Test 3
{
    "3": "d",
    "1": "b",
    "2": "c",
    "0": "a"
}
[
    "a",
    "b",
    "c",
    "d"
]