2012-08-16 25 views
7

मैं PHP में स्ट्रिंग को सॉर्ट करना चाहता हूं, और मैच को स्ट्रिंग के पहले अक्षरों पर सबसे पहले किया जाना चाहिए, फिर पूरे स्ट्रिंग के अक्षरों पर।सॉर्ट स्ट्रिंग्स, पहले अक्षर पहले, फिर शब्दों के अंदर अक्षर

उदाहरण के लिए, अगर किसी को do खोजता है, और सूची

Adolf 
Doe 
Done 

शामिल परिणाम

Doe 
Done 
Adolf 

होना चाहिए नियमित sort($array, SORT_STRING) या ऐसा चीजों का उपयोग करना काम नहीं करता है, एडॉल्फ से पहले सॉर्ट की गई है दूसरे।

क्या किसी को पता है कि यह कैसे करना है?

+1

आप ऐसा नहीं कर सकते यह एक साधारण खोज के साथ। मेरा सुझाव है कि आप जिस घटना की तलाश कर रहे हैं उसकी प्रत्येक स्थिति के लिए, आप इन सूचियों को सॉर्ट करें, कई सूची बनाएं। – Tchoupi

+0

@ user1603166, आपका प्रश्न थोड़ा अस्पष्ट है। रोमन के उदाहरण से, यदि सूची में 'ओडोमीटर' और 'पेट' भी शामिल है, तो इसे कैसे हल किया जाना चाहिए? – Matthew

उत्तर

0

आप stripos($str, $search) पर आधारित तारों को ऑर्डर कर सकते हैं ताकि सामने वाले (stripos() == 0) पहले वाले हों।

निम्न कोड खोज स्ट्रिंग के सबस्ट्रिंग पदों को एक अलग सरणी में धक्का देता है और फिर मैचों को उचित क्रम लागू करने के लिए array_multisort() का उपयोग करता है; usort() के बजाय stripos() पर कॉल करने से बचने के बजाय इसे इस तरह से करना।

$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

यह एक चालाक समाधान है, लेकिन अगर सूची में स्ट्रिंग्स हैं जिनमें '$ search' नहीं है तो यह असफल हो जाएगा। stripos() झूठी वापसी करेगा, जो 0 के बराबर होगा। (अगर सरणी नक्शा झूठी जगह के बजाय एक बड़ी संख्या देता है तो आसानी से संशोधित किया जाता है।) – Matthew

+0

@ मैथ्यू मुझे लगता है कि मिलान पहले से ही एक grep या sth का उपयोग कर किया गया है :) –

+0

बेशक, आदर्श रूप से स्थिति निर्धारण के समान चरण में किया जाना चाहिए ;-) मुझे उस बारे में सोचने दें। –

3

usort(array, callback) आपको कॉलबैक के आधार पर क्रमबद्ध करने देता है।

उदाहरण (कुछ इस तरह है, यह कोशिश नहीं की)

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

मुझे आपका जवाब समझ में नहीं आता है। ठीक है usort मुझे अपने आप पर एक समारोह के साथ क्रमबद्ध करने दें, लेकिन समस्या अभी भी है कि सॉर्टिंग कार्यों मुझे इस मामले में Doe से पहले एडॉल्फ दे। – user1603166

+0

ठीक है, मैं इसके साथ कोशिश करूंगा, धन्यवाद! – user1603166

+0

'usort()' के भीतर कितनी तुलना की जाती है इस पर निर्भर करता है कि यह बहुत भारी हो सकता है :) –

3

मैं एक कस्टम प्रकार का प्रयोग करेंगे:

<?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); 

आउटपुट:

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

+1।हालांकि ओपी को पता होना चाहिए कि 'ओडोमीटर' को 'पेट' से पहले सूचीबद्ध किया जाएगा, जो वांछनीय हो सकता है या नहीं। – Roman

+0

@Roman, मुझे लगता है कि यह खोज का बिंदु है। लेकिन यदि नहीं, तो '$ diff' चेक और' वापसी 'को हटाकर उस व्यवहार को हटा दिया जाएगा। – Matthew

+0

पता नहीं, मुझे लगता है कि इसका उपयोग "स्वत: पूर्ण" सुविधा द्वारा किया जाता है, उस स्थिति में मैं उन सभी परिणामों को पसंद करना चाहता हूं जो वर्णमाला द्वारा क्रमबद्ध 'सुई' से शुरू नहीं होते हैं। – Roman

संबंधित मुद्दे