অবজেক্ট ক্ষেত্র দ্বারা বস্তুর অ্যারে বাছাই করুন


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

দ্বিতীয় আর্গুমেন্ট হিসাবে আপনি যে কোনও কলযোগ্য ব্যবহার করতে পারেন । এখানে কিছু উদাহরন:

  • বেনামে ফাংশন ব্যবহার করে (পিএইচপি 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
  • তীর ফাংশন ব্যবহার করে (পিএইচপি 7.4 থেকে)

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

এছাড়াও, আপনি যদি সাংখ্যিক মানগুলির সাথে তুলনা fn($a, $b) => $a->count - $b->countকরেন, "তুলনা" ফাংশনটি কৌশলটি করা উচিত।


93
এটি দুর্দান্ত, তবে যদি বাছাইকরণ ফাংশনটি কলিং ফাংশনটির মতো একই শ্রেণিতে থাকে তবে আপনার ব্যবহার করা উচিত: usort ($ your_data, অ্যারে ($ এটি, "সিএমপি"));
rmooney

7
@ আরমুনি হ্যাঁ, তবে আপনি যদি কেবল কোনও ক্লাসের মধ্যে থাকেন।
ক্যামব্রাকা


7
অথবা যদি আপনার তুলনা ফাংশনটি আপনার মডেল / অবজেক্টের সাথে তুলনা করছেন (যা আমার মতে একটি ক্লিনার ডিজাইন) আপনি অবশ্যই আপনার মডেল / অবজেক্টের পুরো নাম স্থানটি অবশ্যই এতে অন্তর্ভুক্ত করবেন: ইউএসোর্ট ($ সদস্য, অ্যারে ("পথ" থেকে \ আপনার \ মডেল \ সদস্য "," তুলনাবাইনেম "));
ক্লজিয়ের

3
এটি আমাকে সাজানো কিছুই ফিরিয়ে দেয় না, কেবল সবচেয়ে বড় প্রথম, এবং বাকিগুলি আমি অনিচ্ছিন্ন করে রেখেছি
Alberto Acuña

472

ক্লোজারগুলি ব্যবহার করে এক উত্তম উপায়

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

দয়া করে মনে রাখবেন এটি পিএইচপি'র নথিতে নেই তবে আপনি যদি 5.3+ ক্লোজারগুলি সমর্থন করেন তবে কলযোগ্য আর্গুমেন্ট সরবরাহ করা যেতে পারে।


16
আমি গ্রহণযোগ্য উত্তরের চেয়ে এটিকে আরও ভাল ভালবাসি কারণ আমরা দ্রুত তুলনা ফাংশনটি সংজ্ঞায়িত করতে পারি এবং একটি ক্লাসে ব্যবহার করতে পারি
নাম জি ভিইউ

11
আপনি যদি অ্যারে কীগুলি সংরক্ষণ করতে চান তবেuasort()
gilletech

10
সাজানোর জন্য ডেস্ক,-1 * strcmp($a->name, $b->name);
ওয়ালেস ম্যাক্সটার

17
ডেস্ককে বাছাই করতে গুণনের দরকার নেই। 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

আপনি যদি পিএইচপি ওপ ব্যবহার করে থাকেন তবে আপনার এতে পরিবর্তন করতে হবে:

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

বিটিডব্লিউ, আপনি কোথা থেকে এই অ্যারে পেলেন? আমি আশা করি ডাটাবেস থেকে নয়?


1
আসলে এটি সফল হলে এটি $resultধারণ করবে TRUEএবং আপনার তুলনাটি হওয়া উচিত $a->name > $b->name। :)
ক্যামব্রাকা

2
@ ক্যামব্রাকা: ওহ, রেফারেন্সের মাধ্যমে অ্যারে গ্রহণ করে তা ভুলে গেছেন। বিটিডব্লিউ, ওপি কোনও আদেশ তাকে সংগ্রহের বাছাইয়ের প্রয়োজন বলে দেয়নি।
zerkms

1
আচ্ছা হ্যাঁ, এটি একটি ডাটাবেস :) আসলে এমন কোনও ফাংশন থেকে যা ডেটাবেস থেকে ডেটা পায়
আলেক্স

3
@ অ্যালেক্স: আপনি তখন এটি ডাটাবেসে বাছাই করেন না কেন? ORDER BY count
zerkms

1
এটি আরও জটিল, কারণ এটি ওয়ার্ডপ্রেসের একটি স্টার্ডার্ড ফাংশন, এবং আমি যখন একটি প্লাগইন লিখছি, আমি ডাব্লুপি ফাইলগুলি পরিবর্তন করতে পারি না। আমি আপনার উদাহরণটি create_function ব্যবহার করে চেষ্টা করেছি (কারণ আমি এটি একটি শ্রেণীর অভ্যন্তরে ব্যবহার করছি এবং ফাংশনটির নামটি কীভাবে ব্যবহার করতে পারি তা আমি জানি না): create_function('$a,$b', "return $a->count < $b->count;")তবে আমি এটি কাজ করতে পারি না :( আমি কয়েকটি বিজ্ঞপ্তি পেয়েছি এবং সতর্ক করেছিলাম যে usort প্রত্যাশা 2 প্যারামিটারটি একটি বৈধ কলব্যাক হবে
অ্যালেক্স

9

আপনি এই ফাংশনটি ব্যবহার করতে পারেন (পিএইচপি সংস্করণ> = 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]
স্টিজে

আপনি যে সমাধানটি দেন তা কেবল সহজ বস্তুগুলির জন্য কাজ করে তবে স্টিজের ফিক্সের সাহায্যে এটি ব্যবহার করা সমস্ত বস্তুর অ্যারেগুলির জন্য কাজ করে
ব্যবহারকারী 2993145

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

এখানে সমস্ত উত্তরের বিপরীতে হ'ল তারা স্থির ক্ষেত্রের নাম ব্যবহার করে , তাই আমি ওওপি শৈলীতে একটি সমন্বিত সংস্করণ লিখেছিলাম। ধরে নেওয়া হয়েছে যে আপনি গেটর পদ্ধতি ব্যবহার করছেন আপনি সরাসরি এই ক্লাসটি ব্যবহার করতে পারেন এবং ক্ষেত্রের নামটি প্যারামিটার হিসাবে ব্যবহার করতে পারেন । সম্ভবত কেউ এটি দরকারী মনে হয়।

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

এটি ক্লোজার ক্লাসের উপর ভিত্তি করে তৈরি করা হয়েছে , যা বেনামে ফাংশনগুলিকে অনুমতি দেয়। এটি পিএইচপি 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

আপনি যদি কোডিগিটারের ভিতরে এটি ব্যবহার করে থাকেন তবে আপনি এই পদ্ধতিগুলি ব্যবহার করতে পারেন:

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

@ আরমুনি এই পরামর্শের জন্য আপনাকে ধন্যবাদ। এটা সত্যিই আমাকে সাহায্য করে।


এই কোডিগিটারটি ঠিক কীভাবে নির্দিষ্ট?
জিজিডিএক্স

2

অনুপ্রেরণার জন্য ধন্যবাদ, আমাকে একটি বাহ্যিক-অনুবাদক পরামিতিও যুক্ত করতে হয়েছিল

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

1

আপনার যদি কেবল একটি ক্ষেত্র অনুসারে বাছাই করতে হয় তবে usortএটি একটি ভাল পছন্দ। তবে আপনার একাধিক ক্ষেত্রের দ্বারা বাছাই করতে চাইলে সমাধানটি দ্রুত অগোছালো হয়ে যায়। এই ক্ষেত্রে, YaLinqo লাইব্রেরি * ব্যবহার করা যেতে পারে, যা অ্যারে এবং অবজেক্টের জন্য এসকিউএল-জাতীয় কোয়েরি সিনট্যাক্স প্রয়োগ করে। এটি সব ক্ষেত্রে একটি সুন্দর বাক্য গঠন আছে:

$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

আপনি এনএসপিএল থেকে বাছাই করা ফাংশনটি ব্যবহার করতে পারেন :

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

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.