你真的知道什么是数组吗?

在我工作的地方,我希望Web开发人员具备PHP和JavaScript知识。在进行采访时,我发现只问一个简单的问题就足以了解开发人员对他每天使用的工具的了解程度。问题是:

JavaScript和PHP中的数组之间有什么异同?

编写代码的能力是一回事。还有另一件事-对所使用语言的内部机制的理解。 这个问题的答案给了我关于受访者的全部信息。实际上,几乎每种通用语言都有数组。根据不同语言中的哪些数组或多或少是同一件事来进行假设很容易。许多程序员都这样做。





这是一个不正确的假设,导致许多小错误,导致编写不合理的代码,导致无法有效利用语言的优势。

数组及其母语-C


C语言不是历史上第一种编程语言,但它是对IT行业影响最大的语言。许多开发人员在C机构任教,并将其作为第一语言。PHP和JavaScript都从C那里获取了一些东西。结果,我们可以观察到这些语言和C之间的一些相似之处,正是对C中的数组的分析使我们能够显示出自1972年以来这些数据结构已经发展了多少。

在C语言中,数组是强类型的,并且具有固定的长度。

int myArray[10];
int fibonacci[10] = {0, 1, 1, 2, 3, 5, 8, 13, 21, 34};

上面是几个数组声明。它们只能存储整数,其数量不能超过10。

使用此类数组时,将使用循环for这种模式没有任何实际需要,可以用许多其他编程语言来复制:

int i, sum;
for (i = 0; i < 9; i++) {
  sum += fibonacci[i];
}

这样的设计在JavaScript或PHP中看起来都不是疯狂的。但这就是危险所在。

JavaScript数组


您可以想象JavaScript中的数组与C语言中的数组非常相似。事实是,以下构造在JS中看起来非常正常:

let myArray = [];
let fibonacci = [0, 1, 1, 2, 3, 5, 8, 13, 21, 34];

但是,JavaScript和C语言中的数组是两件事。例如,以下显然在C中是不可能的:

myArray[0] = 5;
myArray[1] = 5.5;
myArray[2] = 'cat';
myArray[3] = [1,2,3];
myArray[4] = (a,b) => {a+b};
myArray[1000] = 'mind blown';
// myArray = [5, 5.5, 'cat', [1,2,3], (a,b) => {a+b}];

在JavaScript中,数组的长度是可变的。它们内容的类型不受控制-就像普通变量的类型一样。语言控制了内存,结果,数组的长度可以增加或减少,并且开发人员无法考虑它。实际上,JavaScript数组与列表非常相似。

可以使用从C借用的不成功方法来组织数组枚举:

let sum = 0;
for (i = 0; i < fibonacci.length; i++) {
  sum += fibonacci[i];
}

但是,我们不需要使用这种方法来枚举JS数组。例如,有不必要的中间变量。在这种设计中,很可能会出现错误,其原因是不确定的或不正确的值。数组元素中是否有任何值fibonacci[10]如果值在那里-是整数吗?

但是JavaScript具有更好的数组处理机制。JS中的数组不仅仅是一些简单的数据结构。它们像函数一样,是一流的对象。他们具有充分解决各种问题的方法:

let sum = fibonacci
   .filter(Number.isInteger)
   .reduce(
      (x,y) => {return x+y}, 0
    );

这比遍历数组好得多for


数组的一些方法

另外,正如已经提到的,与C数组的长度不同,JS中的数组的长度是固定的。这使您可以对影响数组长度的数组产生非常有趣的效果。因此,使用该方法,您可以pop从数组中提取最后一个元素。并且该方法push允许您将新元素添加到数组的末尾。该方法unshift允许您将元素添加到数组的开头。方法shift是提取数组的第一个元素。通过使用这些方法的不同组合,您可以像处理堆栈或队列一样使用数组。这一切都取决于程序员的需求。

PHP中的数组


PHP中的数组几乎类似于JavaScript数组。

它们像JS数组一样,具有可变长度和弱类型。因此,可能很容易断定PHP和JS中的数组是同一回事。

$myArray = [];
$fibonacci = [0, 1, 1, 2, 3, 5, 8, 13, 21, 34];
$myArray[0] = 5;
$myArray[1] = 5.5;
$myArray[2] = 'cat';
$myArray[3] = [1,2,3];
$myArray[4] = function($a, $b) { return $a + $b; };

PHP中的Lambda函数不如JS中的类似函数(在ES6中)那么漂亮,但是用PHP编写的此示例在功能上等同于先前考虑的JS示例。

可以使用,并且上述功能描述类似物将元素添加到阵列和从中检索它们(array_pusharray_poparray_shiftarray_unshift)。

但是在JavaScript(以及C)中,您不能编写与以下内容类似的内容(当然,您可以在JavaScript中编写类似的代码,但不会像在PHP中那样工作):

$myArray['banana'] = 'yellow fruit';
$myArray[5] = 'is alive';
$myArray[0.02] = 'the 2%';

在PHP中,从技术角度来看,数组是哈希表或字典。他们使用键/值对。键可以是任何原始值:整数,浮点数,字符串。由于php数组基于字典,因此在这些数组中查找键值非常有效。即,搜索的时间复杂度为O(1)

这意味着PHP数组可以成功地用作简单的查找表:

$colours = [
  'red' => '#FF0000',
  'green' => '#00FF00',
  'blue' => '#0000FF',
  'orange' => '#FF6600',
];

PHP数组为开发人员提供了很大的灵活性。这些数组可以按键和值排序。例如,您可以使用来“翻转”一个数组array_flip,交换键和值,这使得可以非常有效地组织必要数据数组中的搜索。

在常规数组中查找特定值非常耗时O(n),因为在搜索过程中,您需要检查存储在数组中的每个值。在PHP中,很容易使同一操作的时间复杂度达到O(1)

$users = [
  1 => 'Andi',
  2 => 'Benny',
  3 => 'Cara',
  4 => 'Danny',
  5 => 'Emily',
];
$lookupTable = array_flip($users);
return $lookupTable['Benny'];

当然,JavaScript中也有类似的东西,尽管在这里已经有必要诉诸对象的功能。但是正因为如此,您必须做出一些妥协。也就是说,在处理对象时,开发人员将没有像我们上面讨论的那样的数组方法。

如果继续讨论PHP数组,可以说它们的枚举是简单安全地组织的。在这里可以应用for类似于C的循环,但是在执行此操作之前,您应该仔细考虑为什么要这样做。 PHP借助循环foreach,您可以解决特定于可变长度数组的问题,该数组可以包含不同类型的值:

$sum = 0;
foreach ($myArray as $key => $value) {
  $sum += is_numeric($value) ? $value : 0;
}

循环提供对键和值的访问,这使程序员可以同时使用它们。

值得注意的是,PHP数组与JS数组的不同之处在于,在PHP中,您必须使用其外部的函数对数组执行一些操作:

$sum = 
  array_reduce(
    array_filter($fibonacci, 'is_numeric'),
    function ($x, $y) { return $x + $y; },
    0
  };

它具有功能,但不如JavaScript中的漂亮。如果要编写类似于JavaScript中使用的代码的PHP数组代码(有很强的论点支持此方法),则可能需要查看专门的解决方案。说- Collection来自Laravel框架的类。但是,PHP允许您创建其功能类似于数组的对象(例如,可以在循环中对其进行处理foreach)。

如果PHP是您的主要编程语言,则您会习惯于它,并且完全可以忽略潜伏在其基本机制中的强大功能。

简而言之,PHP数组是该语言最被低估和最不起眼的功能,如果使用正确,它会带来很多好处。

摘要:问答


问题:JavaScript和PHP中的数组之间有什么异同?

:在PHP和JavaScript中,数组本质上是可变长度的弱类型列表。在JavaScript中,数组元素的键是有序整数。在PHP中,可以将数组与支持排序的列表进行比较,并与可以方便地通过键搜索项的字典进行比较。PHP数组的键可以是原始类型的任何值,您可以按键或值对此类数组进行排序。

亲爱的读者们!您认为JavaScript数组最缺乏哪些标准功能?


All Articles