การใช้ usort ใน php ด้วยฟังก์ชันคลาสส่วนตัว


119

ok ใช้ usort กับฟังก์ชั่นไม่ซับซ้อน

นี่คือสิ่งที่ฉันเคยมีมาก่อนในโค้ดเชิงเส้นของฉัน

function merchantSort($a,$b){
    return ....// stuff;
}

$array = array('..','..','..');

จัดเรียงฉันก็ทำ

usort($array,"merchantSort");

ตอนนี้เรากำลังอัปเกรดโค้ดและลบฟังก์ชันส่วนกลางทั้งหมดและวางไว้ในตำแหน่งที่เหมาะสม ตอนนี้รหัสทั้งหมดอยู่ในคลาสและฉันไม่สามารถหาวิธีใช้ฟังก์ชัน usort เพื่อจัดเรียงอาร์เรย์ด้วยพารามิเตอร์ที่เป็น object method แทนที่จะเป็นฟังก์ชันง่ายๆ

class ClassName {
   ...

   private function merchantSort($a,$b) {
       return ...// the sort
   }

   public function doSomeWork() {
   ...
       $array = $this->someThingThatReturnAnArray();
       usort($array,'$this->merchantSort'); // ??? this is the part i can't figure out
   ...

   }
}

คำถามคือฉันจะเรียกวิธีการอ็อบเจ็กต์ภายในฟังก์ชัน usort () ได้อย่างไร

คำตอบ:


228

ทำให้ฟังก์ชันการเรียงลำดับของคุณคงที่:

private static function merchantSort($a,$b) {
       return ...// the sort
}

และใช้อาร์เรย์สำหรับพารามิเตอร์ที่สอง:

$array = $this->someThingThatReturnAnArray();
usort($array, array('ClassName','merchantSort'));

2
นี่มันเยี่ยมมาก! ฉันต้องการชี้ให้เห็นว่าฟังก์ชันการเรียงลำดับไม่จำเป็นต้องประกาศโดยปริยายว่าเป็นวิธีการคงที่ เนื่องจากยังใช้งานได้โดยไม่มี :)
Jimbo

@ Jimbo - นั่นเป็นเหตุผลดังนั้นฟังก์ชันส่วนตัวจึงสามารถใช้การสร้างอินสแตนซ์และตัวแปรคลาสได้ ใช่มันเยี่ยมมาก! ดูคำตอบของ @deceze ด้วยซึ่งคุณสามารถส่งผ่าน$this(neato)
เบ็น

5
หากคุณทำให้ฟังก์ชันคงที่ (ซึ่งคุณควร) คุณสามารถเขียนusort($array, 'ClassName:merchantSort')ได้ไหม?
caw

8
ผู้ชายคนนี้ดูเหมือนจะเป็นวิธีแปลก ๆ ในการทำเช่นนี้ โอ้ PHP เรารักคุณอย่างไร
dudewad

12
@MarcoW. ฉันคิดว่ามีวินาทีที่ขาดหายไประหว่าง ClassName และ MerchantSort นอกจากนี้หากมีการใช้ฟังก์ชันภายในคลาสเดียวกันฉันได้ทดสอบแล้ว'self::merchantSort'และใช้งานได้
Pere


21

คุณต้องผ่าน$thisเช่น:usort( $myArray, array( $this, 'mySort' ) );

ตัวอย่างเต็ม:

class SimpleClass
{                       
    function getArray( $a ) {       
        usort( $a, array( $this, 'nameSort' ) ); // pass $this for scope
        return $a;
    }                 

    private function nameSort( $a, $b )
    {
        return strcmp( $a, $b );
    }              

}

$a = ['c','a','b']; 
$sc = new SimpleClass();
print_r( $sc->getArray( $a ) );

ภาคสองตอนนี้ดีขึ้นมาก แต่คุณยังขาด ")" ในตัวอย่างแรกของคุณ
codecribblr

5

ในตัวอย่างนี้ฉันกำลังจัดเรียงตามฟิลด์ภายในอาร์เรย์ที่เรียกว่า AverageVote

คุณสามารถรวมวิธีการไว้ในการโทรซึ่งหมายความว่าคุณไม่มีปัญหาขอบเขตคลาสอีกต่อไปเช่นนี้ ...

        usort($firstArray, function ($a, $b) {
           if ($a['AverageVote'] == $b['AverageVote']) {
               return 0;
           }

           return ($a['AverageVote'] < $b['AverageVote']) ? -1 : 1;
        });

1
ซึ่งเหมาะสมก็ต่อเมื่อคุณใช้ฟังก์ชันนี้ในการจัดเรียงเดียวเท่านั้น ในหลาย ๆ กรณีจะใช้การเปรียบเทียบแบบเดียวกันในหลาย ๆ ที่
ผ้าไหม

1
นี่เหมาะสำหรับสิ่งที่ฉันต้องทำ ขอบคุณ!
Christopher Smit

3

ในคลาสโมเดล Laravel (5.6) ฉันเรียกมันแบบนี้ทั้งสองวิธีเป็นแบบสาธารณะโดยใช้ php 7.2 บน windows 64 บิต

public static function usortCalledFrom() 

public static function myFunction()

ฉันโทรหา usortCalledFrom () แบบนี้

usort($array,"static::myFunction")

สิ่งเหล่านี้ไม่ได้ผล

usort($array,"MyClass::myFunction")
usort($array, array("MyClass","myFunction")

static::แทนที่จะเป็นชื่อชั้นเรียนคือสิ่งที่ฉันต้องการขอบคุณที่พูดถึงมัน
จริงใจ
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.