保持数组在PHP中排序

时间:2009-01-29 06:20:28

标签: php arrays sorting

我有一个PHP脚本,它读取大型CSV并执行某些操作,但前提是“用户名”字段是唯一的。 CSV用于多个脚本,因此将输入从CSV更改为仅包含唯一用户名不是一种选择。

非常基本的程序流程(我想知道)是这样的:

$allUsernames = array();
while($row = fgetcsv($fp)) {
    $username = $row[0];
    if (in_array($username, $allUsernames)) continue;
    $allUsernames[] = $username;
    // process this row
}

由于这个CSV实际上可能非常大,所以in_array位让我思考。在数组中搜索成员时最理想的情况是它是否已经排序,所以如何从头开始构建数组,保持顺序?一旦它有序,是否有比使用in_array()更有效的搜索方式,考虑到它可能不知道数组是否已排序?

4 个答案:

答案 0 :(得分:9)

不保持数组有序,但这种优化怎么样?我猜isset()数组键应该比in_array()搜索更快。

$allUsernames = array();
while($row = fgetcsv($fp)) {
  $username = $row[0];

  if (isset($allUsernames[$username])) {
    continue;
  } else {
    $allUsernames[$username] = true;

    // do stuff
  }
}

答案 1 :(得分:4)

以排序顺序从头开始构建数组的方法是插入排序。在PHP-ish伪代码中:

$list = []
for ($element in $elems_to_insert) {
     $index = binary_search($element, $list);
     insert_into_list($element, $list, $index);
}

虽然,实际上可能会更快地以未排序的顺序创建数组,然后使用quicksort(PHP的内置排序函数使用quicksort)

并在排序列表中查找元素:

function binary_search($list, $element) {
    $start = 0;
    $end = count($list);
    while ($end - $start > 1) {
        $mid = ($start + $end) / 2;
        if ($list[$mid] < $element){
            $start = $mid;
        }
        else{
            $end = $mid;
        }
    }
    return $end;
}

使用此实现,您必须测试$list[$end]以查看它是否是您想要的元素,因为如果元素不在数组中,则会找到应该插入的点。我是这样做的,所以它与之前的代码示例一致。如果需要,可以在函数本身中检查$list[$end] === $element

答案 2 :(得分:1)

php中的数组类型是有序映射(php array type)。如果你将int或字符串作为键传入,你将有一个有序的地图......

请查看以上链接中的第6项。

答案 3 :(得分:0)

in_array()不会受益于排序数组。 PHP只是沿着整个数组走,好像它是一个链表。