将一行Perl转换为PHP

时间:2014-11-06 15:58:12

标签: php perl

我正在将文件从Perl转换为PHP,但我需要帮助这一行:
@stuff_unique = grep !$list{$_}++, @stuff;
我知道stuff_uniquestuff是数组。

2 个答案:

答案 0 :(得分:7)

这是一种常见的Perl习语,在perlfaq4

中有描述

使用此结构,@stuff_unique最终会得到@stuff中至少看过一次的项目列表;换句话说,在没有重复的意义上,它只保留唯一的值。它的工作方式是:

Perl中的哈希就像一个具有唯一键的关联数组。 %list就是这样的哈希。 $list{something}是该哈希中名为“something”的元素。它的价值可以是你放在它里面的任何东西。

grep遍历@stuff中的项目。对于stuff中的每个项目,该项目将用作%list哈希中的哈希键。 ++递增该对应哈希元素的值。因此,如果@stuff包含“1,2,1”,则在第一次迭代时将创建名为“1”的哈希元素。它没有值,转换为布尔值false。前面的!反转布尔意义。因此,在第一次迭代中,'1'哈希元素的false值被计算为true,因此该元素将传递给@stuff_unique。最后,发生后增量,因此1哈希元素中保存的值递增为1.

在第二个元素上,2还没有被看到,因此它会通过,并且其相应的哈希元素也会增加到1.

在第三次迭代中,再次看到“1”。 $list{1}已经等于1,这是一个真正的值。真的是假的;所以这个不会传递给@stuff_unique

@stuff中的元素将以这种方式逐一测试;检测他们以前是否曾被看见,如果他们没有看到,他们会通过@stuff_unique

PHP提供了一个名为array_unique的函数,它应该为您做同样的事情。它会像这样使用:

$stuff_unique = array_unique($stuff);

幸运的是,对于Perl人来说,这是一个线性时间操作。不幸的是,对于PHP人员来说,这是通过对输入数组进行排序,然后在其上进行迭代,在此过程中跳过重复项来实现的。这意味着它是一个O(n + n log n)操作(简化为O(n log n)),也就是说,它的实现不能像普通的Perl习惯一样扩展。

答案 1 :(得分:2)

使用php闭包的乐趣,

<?php

$stuff = array(1,1,2,2,2,3,3,3);

$list = array();
$stuff_unique = array_filter($stuff, function($_) use (&$list) {
  return !$list[$_]++;
});

print_r(array_values($stuff_unique));

<?php

$stuff = array(1,1,2,2,2,3,3,3);
$stuff_unique = array_keys(array_flip($stuff));

print_r($stuff_unique);

$stuff_unique = array_values(array_unique($stuff));