2012-08-16 48 views
7

Tôi muốn sắp xếp các chuỗi trong PHP và kết quả phù hợp nhất trên các chữ cái đầu tiên của chuỗi con, sau đó trên các chữ cái của toàn bộ chuỗi.Sắp xếp các chuỗi, các chữ cái đầu tiên trước tiên, sau đó các chữ cái bên trong các từ

Ví dụ, nếu ai đó tìm kiếm do, và danh sách chứa

Adolf 
Doe 
Done 

kết quả nên

Doe 
Done 
Adolf 

Sử dụng thường xuyên sort($array, SORT_STRING) hoặc những thứ tương tự không hoạt động, Adolf được sắp xếp trước những người khác.

Có ai đó có ý tưởng cách thực hiện điều đó không?

+1

Bạn không thể làm nó với một tìm kiếm đơn giản. Tôi đề nghị bạn tạo nhiều danh sách, cho mỗi vị trí của sự xuất hiện mà bạn đang tìm kiếm, sau đó sắp xếp các danh sách con này. – Tchoupi

+0

@ user1603166, câu hỏi của bạn hơi mơ hồ. Từ ví dụ của @ Roman, nếu danh sách cũng bao gồm 'Odometer' và' Abdomen', nó nên được sắp xếp như thế nào? – Matthew

Trả lời

0

Bạn có thể đặt hàng các chuỗi dựa trên stripos($str, $search) sao cho các chuỗi ở mặt trước (stripos() == 0) sẽ xuất hiện trước.

Đoạn mã sau đẩy vị trí chuỗi con của chuỗi tìm kiếm vào một mảng riêng biệt và sau đó sử dụng array_multisort() để áp dụng thứ tự thích hợp cho các kết quả phù hợp; làm theo cách này thay vì usort() tránh phải gọi số stripos() nhiều lần.

$k = array_map(function($v) use ($search) { 
    return stripos($v, $search); 
}, $matches); 

// $k contains all the substring positions of the search string for all matches 

array_multisort($k, SORT_NUMERIC, $matches, SORT_STRING); 

// $matches is now sorted against the position 
+0

Đây là một giải pháp thông minh, nhưng nó sẽ thất bại nếu danh sách có các chuỗi không chứa '$ search'. stripos() sẽ trả về false, được cân bằng với 0. (Dễ dàng sửa đổi nếu mảng bản đồ trả về một số lớn thay vì sai.) – Matthew

+0

@Matthew Tôi giả định kết hợp đã được thực hiện bằng cách sử dụng grep hoặc sth :) –

+0

Tất nhiên, lý tưởng là nên được thực hiện trong cùng một bước như xác định vị trí ;-) hãy để tôi suy nghĩ về điều đó. –

3

usort(array, callback) cho phép bạn sắp xếp dựa trên gọi lại.

dụ (một cái gì đó như thế này, không thử nó)

usort($list, function($a, $b) { 
    $posa = strpos(tolower($a), 'do'); 
    $posb = strpos(tolower($b), 'do'); 
    if($posa != 0 && $posb != 0)return strcmp($a, $b); 
    if($posa == 0 && $posb == 0)return strcmp($a, $b); 
    if($posa == 0 && $posb != 0)return -1; 
    if($posa != 0 && $posb == 0)return 1; 
}); 
+0

Tôi không hiểu câu trả lời của bạn. Ok usort cho phép tôi sắp xếp với một chức năng của riêng tôi, nhưng vấn đề vẫn là chức năng phân loại cho tôi Adolf trước Doe trong trường hợp này. – user1603166

+0

Ok tôi sẽ cố gắng với điều đó, cảm ơn! – user1603166

+0

Tùy thuộc vào có bao nhiêu so sánh được thực hiện trong 'usort()' điều này có thể nhận được khá nặng :) –

3

Tôi sẽ sử dụng một loại tùy chỉnh:

<?php 
$list = ['Adolf', 'Doe', 'Done']; 

function searchFunc($needle) 
{ 
    return function ($a, $b) use ($needle) 
    { 
    $a_pos = stripos($a, $needle); 
    $b_pos = stripos($b, $needle); 

    # if needle is found in only one of the two strings, sort by that one 
    if ($a_pos === false && $b_pos !== false) return 1; 
    if ($a_pos !== false && $b_pos === false) return -1; 

    # if the positions differ, sort by the first one 
    $diff = $a_pos - $b_pos; 
    # alternatively: $diff = ($b_pos === 0) - ($a_pos === 0) 
    if ($diff) return $diff; 

    # else sort by natural case 
    return strcasecmp($a, $b); 

    }; 
} 

usort($list, searchFunc('do')); 

var_dump($list); 

Output:

array(3) { 
    [0] => 
    string(3) "Doe" 
    [1] => 
    string(4) "Done" 
    [2] => 
    string(5) "Adolf" 
} 
+1

+1.Mặc dù OP nên lưu ý rằng ở đây 'Đo dặm' sẽ được liệt kê trước 'Bụng', có thể có hoặc không mong muốn. – Roman

+0

@Roman, tôi nghĩ đó là điểm tìm kiếm. Nhưng nếu không, loại bỏ kiểm tra '$ diff' và' return' sẽ loại bỏ hành vi đó. – Matthew

+0

Không biết, tôi đoán nó được sử dụng bởi một loại tính năng "tự động hoàn thành", trong trường hợp đó tôi muốn có tất cả các kết quả mà 'không bắt đầu với $ kim' được sắp xếp theo bảng chữ cái. – Roman

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