2009-01-29 40 views
10

Tôi có một tập lệnh PHP đọc một tệp CSV lớn và thực hiện các hành động nhất định, nhưng chỉ khi trường "tên người dùng" là duy nhất. CSV được sử dụng trong nhiều hơn một tập lệnh, do đó việc thay đổi đầu vào từ CSV thành chỉ chứa tên người dùng duy nhất không phải là một tùy chọn.Giữ một mảng được sắp xếp theo PHP

Các chương trình rất cơ bản (mà tôi đang tự hỏi về) dòng chảy đi như thế này:

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

Kể từ CSV này thực sự có thể là khá lớn, đó là in_array chút trong đó có tôi đã suy nghĩ. Tình huống lý tưởng nhất khi tìm kiếm thông qua một mảng cho một thành viên là nếu nó đã được sắp xếp, do đó, làm thế nào bạn sẽ xây dựng một mảng từ đầu, giữ nó theo thứ tự? Một khi nó là theo thứ tự, sẽ có một cách hiệu quả hơn để tìm kiếm nó hơn bằng cách sử dụng in_array(), xem xét rằng nó có lẽ không biết mảng được sắp xếp?

Trả lời

9

Không giữ mảng theo thứ tự, nhưng làm thế nào về loại tối ưu hóa này? Tôi đoán isset() cho khóa mảng phải nhanh hơn tìm kiếm in_array().

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

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

    // do stuff 
    } 
} 
+0

hoặc array_key_exists? – dylanfm

+0

Đúng, bạn cũng có thể làm điều đó, nhưng tôi vẫn đánh giá sự khác biệt giữa hai điều đó. Bạn không bao giờ biết với PHP - một trong những có thể là O (1), trong khi O (n) ... (đề cập đến "làm array_flip() hai lần" lừa) –

+0

Tôi muốn nói nó là "array_key_exists()". Mảng PHP là băm, chúng được tối ưu hóa cho loại công cụ truy cập ngẫu nhiên này. – Tomalak

1

Loại mảng trong php là bản đồ được sắp xếp (php array type). Nếu bạn chuyển vào một trong hai int hoặc chuỗi dưới dạng khóa, bạn sẽ có một bản đồ được sắp xếp ...

Vui lòng xem lại mục số 6 trong liên kết ở trên.

+0

Ý bạn là ví dụ số 6? Cách tôi đọc đó là các mảng được sắp xếp theo thứ tự, mà không nhất thiết phải tương đương với việc sắp xếp: chúng chỉ có một thứ tự cho chúng. – nickf

+0

@nickf: Các mảng PHP là các bản đồ băm, được lập chỉ mục bởi khóa mảng. Thứ tự nội bộ không liên quan đến việc truy cập các giá trị. – Tomalak

+0

ok có ý nghĩa, nhưng đó chỉ là chìa khóa của mảng, phải không? điều đó sẽ không giúp bạn tìm một giá trị cụ thể trong mảng. – nickf

4

Cách xây dựng một mảng từ đầu trong thứ tự sắp xếp là một loại sắp xếp. Trong PHP-ish giả:

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

Mặc dù, nó có thể thực sự bật ra được nhanh hơn để chỉ cần tạo các mảng theo thứ tự không được phân loại và sau đó sử dụng quicksort (chức năng phân loại được xây dựng trong PHP sử dụng quicksort)

Và để tìm một phần tử trong danh sách được sắp xếp:

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; 
} 

với thực hiện điều này, bạn sẽ phải kiểm tra $list[$end] để xem nếu nó là yếu tố mà bạn muốn, vì nếu phần tử không có trong mảng, điều này sẽ tìm ra điểm nơi nó sẽ được chèn vào. Tôi đã làm theo cách đó để nó phù hợp với mẫu mã trước đó. Nếu muốn, bạn có thể kiểm tra $list[$end] === $element trong chính chức năng đó.

+0

Tôi tò mò là tại sao bạn lại thực hiện 'insert_into_list'. Tôi đoán nó là bởi vì nó không đơn giản trong PHP. Bạn sẽ có danh sách Roll Your Own (tức là danh sách liên kết), bởi vì ngay cả SPLDoublyLinkedList cũng không hỗ trợ chèn vào một chỉ mục. Và mảng PHP, là một hashmap, không phải là một danh sách liên kết.Thêm/chèn vào một mảng, chỉ cần thêm vào phần cuối của thứ tự 'tự nhiên' của mảng (tức là thứ tự nó trả về các phần tử lặp lại trên chúng). Tôi đang bỏ phiếu cho bạn mặc dù coz bạn là người duy nhất bắt đầu giải quyết phần 'Giữ một mảng được sắp xếp' của câu hỏi. –

+0

@ Jason tôi đã bỏ nó ra bởi vì nó không liên quan đến câu trả lời. Câu hỏi đã không hỏi làm thế nào để chèn một mục vào một danh sách, và nó rõ ràng từ tên chức năng những gì nó làm; không cần phải thực hiện tham chiếu để hiểu hành vi chính xác. –

0

in_array() không được hưởng lợi từ việc có mảng được sắp xếp. PHP chỉ đi dọc theo toàn bộ mảng như thể nó là một danh sách liên kết.

+0

tôi figured rằng - đọc câu cuối cùng của câu hỏi một lần nữa. – nickf

Các vấn đề liên quan