ऑब्जेक्ट फ़ील्ड द्वारा ऑब्जेक्ट की सॉर्ट करें


514

मैं इस तरह की वस्तुओं को अपने किसी एक क्षेत्र, nameया जैसे कैसे वर्गीकृत कर सकता हूं count?

  Array
(
    [0] => stdClass Object
        (
            [ID] => 1
            [name] => Mary Jane
            [count] => 420
        )

    [1] => stdClass Object
        (
            [ID] => 2
            [name] => Johnny
            [count] => 234
        )

    [2] => stdClass Object
        (
            [ID] => 3
            [name] => Kathy
            [count] => 4354
        )

   ....

जवाबों:


698

Usort का उपयोग करें , यहां एक उदाहरण मैनुअल से अनुकूलित है:

function cmp($a, $b) {
    return strcmp($a->name, $b->name);
}

usort($your_data, "cmp");

आप दूसरे तर्क के रूप में किसी भी कॉल करने योग्य का उपयोग कर सकते हैं । यहाँ कुछ उदाहरण हैं:

  • अनाम फ़ंक्शंस का उपयोग करना (PHP 5.3 से)

    usort($your_data, function($a, $b) {return strcmp($a->name, $b->name);});
  • एक कक्षा के अंदर से

    usort($your_data, array($this, "cmp")); // "cmp" should be a method in the class
  • एरो फ़ंक्शंस का उपयोग करना (PHP 7.4 से)

    usort($your_data, fn($a, $b) => strcmp($a->name, $b->name));

इसके अलावा, यदि आप संख्यात्मक मानों की तुलना कर रहे हैं, तो fn($a, $b) => $a->count - $b->count"तुलना" फ़ंक्शन को चाल करना चाहिए।


93
यह बहुत अच्छा है, लेकिन यदि सॉर्टिंग फ़ंक्शन कॉलिंग फ़ंक्शन के समान वर्ग में है, तो आपको उपयोग करना चाहिए: usort ($ your_data, array (यह, "cmp"));
rmooney

7
@rmooney हाँ, लेकिन केवल तब जब आप किसी कक्षा के अंदर हों।
२०:३३


7
या यदि आपका तुलनात्मक फ़ंक्शन आपके मॉडल / ऑब्जेक्ट में है, जिसकी आप तुलना कर रहे हैं (जो मेरी राय में एक क्लीनर डिज़ाइन है) तो आपको अपने मॉडल / ऑब्जेक्ट का पूरा नामस्थान इस तरह शामिल करना होगा: uasort ($ सदस्यों, सरणी) ("Path \ to" \ your \ मॉडल \ "सदस्य," तुलनानाम "));
1939 में क्लूजियर

3
इसने मुझे कुछ भी नहीं दिया है, बस सबसे पहले सबसे बड़ा, और बाकी सब मैं बेचैन हूँ
अल्बर्टो एक्यूना

472

निकटता का उपयोग करते हुए एक अच्छा तरीका है

usort($your_data, function($a, $b)
{
    return strcmp($a->name, $b->name);
});

कृपया ध्यान दें कि यह PHP के दस्तावेज़ीकरण में नहीं है, लेकिन यदि आप 5.3+ क्लोजर का उपयोग करते हैं तो कॉल करने योग्य तर्क प्रदान किए जा सकते हैं।


16
मुझे यह स्वीकार किए गए उत्तर से बेहतर लगता है क्योंकि हम तुलनात्मक फ़ंक्शन को जल्दी से परिभाषित कर सकते हैं और कक्षा में उपयोग कर सकते हैं
Nam G VU

11
यदि आप सरणी कुंजियों के उपयोग को संरक्षित करना चाहते हैंuasort()
gillytech

10
सॉर्ट desc के लिए,-1 * strcmp($a->name, $b->name);
वालेस मैक्सटर्स

17
Desc को सॉर्ट करने के लिए गुणा करने की आवश्यकता नहीं है। बस स्वैप strcmp($b->name, $a->name)
आर्गन्स

3
आप मेरी तरह एक स्थिति का सामना कर सकते हैं, जहां स्वीकृत जवाब इस पर बेहतर है। उदाहरण के लिए, आपके पास एक माता-पिता और एक बच्चा वर्ग हो सकता है। चाइल्ड क्लास एक फ़ंक्शन को ओवरराइड करता है जो उपयोग करता है usortलेकिन तुलना फ़ंक्शन समान है। इसका उपयोग करने के लिए आपको बंद करने के लिए कोड की नकल करने की आवश्यकता होगी बजाय एक protected staticविधि के कॉल करने के लिए जिसे आपको मूल वर्ग में केवल एक बार परिभाषित करना होगा।
पेरे

48

यदि आप पूर्णांक मानों को क्रमबद्ध करना चाहते हैं:

// Desc sort
usort($array,function($first,$second){
    return $first->number < $second->number;
});

// Asc sort
usort($array,function($first,$second){
    return $first->number > $second->number;
});

स्ट्रिंग के साथ अद्यतन एक ही रजिस्टर (ऊपरी या निचले) में परिवर्तित करने के लिए मत भूलना

// Desc sort
usort($array,function($first,$second){
    return strtolower($first->text) < strtolower($second->text);
});

// Asc sort
usort($array,function($first,$second){
    return strtolower($first->text) > strtolower($second->text);
});

44

यदि आप php oop का उपयोग कर रहे हैं, तो आपको इसे बदलने की आवश्यकता हो सकती है:

public static function cmp($a, $b) 
{
    return strcmp($a->name, $b->name);
}

//in this case FUNCTION_NAME would be cmp
usort($your_data, array('YOUR_CLASS_NAME','FUNCTION_NAME')); 

28
usort($array, 'my_sort_function');

var_dump($array);

function my_sort_function($a, $b)
{
    return $a->name < $b->name;
}

एक ही कोड countफ़ील्ड के साथ होगा ।

के बारे में अधिक जानकारी usort: http://ru2.php.net/usort

Btw, आपको वह सरणी कहां से मिली? मुझे उम्मीद है कि डेटाबेस से नहीं?


1
वास्तव $resultमें TRUEअगर यह सफल होगा, और आपकी तुलना होनी चाहिए $a->name > $b->name। :)
कैम्ब्रैका

2
@cambraca: ओह, यह भूल गया कि संदर्भ द्वारा सरणी को स्वीकार करता है। Btw, ओपी ने यह नहीं बताया कि किस क्रम में उसे संग्रह को क्रमबद्ध करने की आवश्यकता है।
zerkms

1
ठीक है, यह एक डेटाबेस है :) वास्तव में एक फ़ंक्शन से है जो डेटाबेस से डेटा प्राप्त करता है
एलेक्स

3
@ एलेक्स: क्यों आप इसे तब डेटाबेस में सॉर्ट नहीं करते हैं? ORDER BY count
zerkms

1
यह अधिक जटिल है, क्योंकि यह वर्डप्रेस का एक स्टैडर्ड फ़ंक्शन हिस्सा है, और जैसा कि मैं एक प्लगइन लिख रहा हूं, मैं wp फ़ाइलों को नहीं बदल सकता। मैंने create_function का उपयोग करके आपके उदाहरण की कोशिश की (क्योंकि मैं इसे एक वर्ग के अंदर उपयोग कर रहा हूं और मुझे पता नहीं है कि फ़ंक्शन का नाम usort कैसे पास करें): create_function('$a,$b', "return $a->count < $b->count;")लेकिन मैं इसे काम नहीं कर सकता :( मुझे कुछ नोटिस और चेतावनी मिली है कि usort को उम्मीद है कि पैरामीटर 2 एक वैध कॉलबैक होगा
एलेक्स

9

आप इस फ़ंक्शन का उपयोग कर सकते हैं (PHP संस्करण में काम करता है = = 5.3):

function sortArrayByKey(&$array,$key,$string = false,$asc = true){
    if($string){
        usort($array,function ($a, $b) use(&$key,&$asc)
        {
            if($asc)    return strcmp(strtolower($a{$key}), strtolower($b{$key}));
            else        return strcmp(strtolower($b{$key}), strtolower($a{$key}));
        });
    }else{
        usort($array,function ($a, $b) use(&$key,&$asc)
        {
            if($a[$key] == $b{$key}){return 0;}
            if($asc) return ($a{$key} < $b{$key}) ? -1 : 1;
            else     return ($a{$key} > $b{$key}) ? -1 : 1;

        });
    }
}

उदाहरण:

sortArrayByKey($yourArray,"name",true); //String sort (ascending order)
sortArrayByKey($yourArray,"name",true,false); //String sort (descending order)
sortArrayByKey($yourArray,"id"); //number sort (ascending order)
sortArrayByKey($yourArray,"count",false,false); //number sort (descending order)

मैंने उपयोग किया $a->{$key}और $b->{$key}इसके बजाय $a[$key]और $b[$key]जैसा कि हम कर रहे हैं, कड़ाई से बोल रहे हैं, सरणी के सदस्यों के बजाय गुणों से निपट रहे हैं, लेकिन यह अभी भी वह जवाब था जिसकी मुझे तलाश थी।
SteJ

कृपया उदाहरण के कोड में @ SteJ के सुझाव को लागू करें क्योंकि आप जो समाधान देते हैं, वह केवल साधारण वस्तुओं के लिए काम करता है, लेकिन SteJ के फिक्स के साथ यह उन सभी वस्तुओं के लिए काम करता है, जिन पर मैंने कोशिश की है
user2993145

6

आप usortइस तरह का उपयोग कर सकते हैं :

usort($array,function($first,$second){
    return strcmp($first->name, $second->name);
});

5

यदि सब कुछ यहाँ विफल रहता है तो दूसरा उपाय है:

$names = array(); 
foreach ($my_array as $my_object) {
    $names[] = $my_object->name; //any object field
}

array_multisort($names, SORT_ASC, $my_array);

return $my_array;

आपको इस समाधान के लिए ऑस्कर मिलना चाहिए! ))))) थैंक्यू
इमबैंकबुल

4

यहां सभी उत्तरों के नीचे यह है कि वे स्थैतिक क्षेत्र के नामों का उपयोग करते हैं , इसलिए मैंने OOP शैली में एक समायोजित संस्करण लिखा। माना जाता है कि आप गेट्टर विधियों का उपयोग कर रहे हैं जो आप सीधे इस वर्ग का उपयोग कर सकते हैं और पैरामीटर के रूप में फ़ील्ड नाम का उपयोग कर सकते हैं । शायद किसी को यह उपयोगी लगता है।

class CustomSort{

    public $field = '';

    public function cmp($a, $b)
    {
        /**
         * field for order is in a class variable $field
         * using getter function with naming convention getVariable() we set first letter to uppercase
         * we use variable variable names - $a->{'varName'} would directly access a field
         */
        return strcmp($a->{'get'.ucfirst($this->field)}(), $b->{'get'.ucfirst($this->field)}());
    }

    public function sortObjectArrayByField($array, $field)
    {
        $this->field = $field;
        usort($array, array("Your\Namespace\CustomSort", "cmp"));;
        return $array;
    }
} 


3

एक सरल विकल्प जो आपको गतिशील रूप से उस क्षेत्र को निर्धारित करने की अनुमति देता है जिस पर छंटाई आधारित है:

$order_by = 'name';
usort($your_data, function ($a, $b) use ($order_by)
{
    return strcmp($a->{$order_by}, $b->{$order_by});
});

यह क्लोजर क्लास पर आधारित है , जो अनाम कार्यों की अनुमति देता है। यह PHP 5.3 के बाद से उपलब्ध है।


2

यदि आपको स्थानीय आधारित स्ट्रिंग तुलना की आवश्यकता है, तो आप strcollइसके बजाय उपयोग कर सकते हैं strcmp

पहली बार उपयोग करने के लिए याद setlocaleके साथ LC_COLLATEअगर जरूरत सेट स्थानिक जानकारियां करने के लिए।

  usort($your_data,function($a,$b){
    setlocale (LC_COLLATE, 'pl_PL.UTF-8'); // Example of Polish language collation
    return strcoll($a->name,$b->name);
  });

2

यदि आप Codeigniter के अंदर इसका उपयोग कर रहे हैं, तो आप विधियों का उपयोग कर सकते हैं:

usort($jobs, array($this->job_model, "sortJobs"));  // function inside Model
usort($jobs, array($this, "sortJobs")); // Written inside Controller.

@rmooney सुझाव के लिए धन्यवाद। यह वास्तव में मेरी मदद करता है।


यह कोडिग्निटर वास्तव में कितना विशिष्ट है?
ggdx

2

प्रेरणाओं के लिए धन्यवाद, मुझे एक बाहरी $ अनुवादक पैरामीटर भी जोड़ना पड़ा

usort($listable_products, function($a, $b) {
    global $translator;
    return strcmp($a->getFullTitle($translator), $b->getFullTitle($translator));
});

1

यदि आपको केवल एक क्षेत्र के आधार पर छाँटने की आवश्यकता है, तो usortएक अच्छा विकल्प है। हालाँकि, यदि आप कई फ़ील्ड्स को सॉर्ट करना चाहते हैं, तो समाधान जल्दी से गड़बड़ हो जाता है। इस स्थिति में, YaLinqo पुस्तकालय * का उपयोग किया जा सकता है, जो सरणियों और वस्तुओं के लिए SQL- जैसे क्वेरी सिंटैक्स को लागू करता है। इसमें सभी मामलों के लिए एक बहुत ही वाक्यविन्यास है:

$sortedByName         = from($objects)->orderBy('$v->name');
$sortedByCount        = from($objects)->orderBy('$v->count');
$sortedByCountAndName = from($objects)->orderBy('$v->count')->thenBy('$v->name');

यहाँ, के '$v->count'लिए एक शॉर्टहैंड है function ($v) { return $v->count; }(या तो इस्तेमाल किया जा सकता है)। ये विधि श्रृंखला पुनरावृत्तियों को लौटाती है, लेकिन आप ->toArray()अंत में आवश्यकता पड़ने पर जोड़कर एरेज़ प्राप्त कर सकते हैं ।

* मेरे द्वारा विकसित


1

आप Nspl से सॉर्ट किए गए फ़ंक्शन का उपयोग कर सकते हैं :

use function \nspl\a\sorted;
use function \nspl\op\propertyGetter;
use function \nspl\op\methodCaller;

// Sort by property value
$sortedByCount = sorted($objects, propertyGetter('count'));

// Or sort by result of method call
$sortedByName = sorted($objects, methodCaller('getName'));

कृपया यह बताएं कि ओपी को एक अतिरिक्त अतिरिक्त पुस्तकालय की आवश्यकता क्यों होगी, जो कि निर्मित कार्यों में एक सुविधा प्रदान करने के लिए आवश्यक हो
ggdx

1

उपयोगिता वर्ग के लिए मेरे पास यही है

class Util
{
    public static function sortArrayByName(&$arrayToSort, $meta) {
        usort($arrayToSort, function($a, $b) use ($meta) {
            return strcmp($a[$meta], $b[$meta]);
        });
    }
}

इसे कहते हैं:

Util::sortArrayByName($array, "array_property_name");

1

आप इस तरह से usort का उपयोग कर सकते हैं

यदि आप संख्या के आधार पर छाँटना चाहते हैं:

function cmp($a, $b)
{
    if ($a == $b) {
        return 0;
    }
    return ($a < $b) ? -1 : 1;
}

$a = array(3, 2, 5, 6, 1);

usort($a, "cmp");

या एबीसी चार:

function cmp($a, $b)
{
    return strcmp($a["fruit"], $b["fruit"]);
}

$fruits[0]["fruit"] = "lemons";
$fruits[1]["fruit"] = "apples";
$fruits[2]["fruit"] = "grapes";

usort($fruits, "cmp");

और देखें: https://www.php.net/manual/en/function.usort.php

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.