PHP Diziyi Alt Dizi Değerine Göre Sırala


110

Aşağıdaki dizi yapısına sahibim:

Array
        (
            [0] => Array
                (
                    [configuration_id] => 10
                    [id] => 1
                    [optionNumber] => 3
                    [optionActive] => 1
                    [lastUpdated] => 2010-03-17 15:44:12
                )

            [1] => Array
                (
                    [configuration_id] => 9
                    [id] => 1
                    [optionNumber] => 2
                    [optionActive] => 1
                    [lastUpdated] => 2010-03-17 15:44:12
                )

            [2] => Array
                (
                    [configuration_id] => 8
                    [id] => 1
                    [optionNumber] => 1
                    [optionActive] => 1
                    [lastUpdated] => 2010-03-17 15:44:12
                )
    )

Diziyi,? 'Ye göre artımlı bir şekilde sıralamanın en iyi yolu nedir optionNumber?

Yani sonuçlar şöyle görünür:

Array
        (
            [0] => Array
                (
                    [configuration_id] => 8
                    [id] => 1
                    [optionNumber] => 1
                    [optionActive] => 1
                    [lastUpdated] => 2010-03-17 15:44:12
                )

            [1] => Array
                (
                    [configuration_id] => 9
                    [id] => 1
                    [optionNumber] => 2
                    [optionActive] => 1
                    [lastUpdated] => 2010-03-17 15:44:12
                )

            [2] => Array
                (
                    [configuration_id] => 10
                    [id] => 1
                    [optionNumber] => 3
                    [optionActive] => 1
                    [lastUpdated] => 2010-03-17 15:44:12
                )
    )

Yanıtlar:


204

Kullanın usort.

function cmp_by_optionNumber($a, $b) {
  return $a["optionNumber"] - $b["optionNumber"];
}

...

usort($array, "cmp_by_optionNumber");

PHP -5.3'te, bunun yerine anonim bir işlev kullanmalısınız:

usort($array, function ($a, $b) {
    return $a['optionNumber'] - $b['optionNumber'];
});

Yukarıdaki her iki kodun $a['optionNumber']da bir tamsayı olduğunu varsaydığına dikkat edin . @St kullanın . John Johnson'ın çözümü, eğer dizeler ise.


PHP -7.0'da taşma / kesme sorunlarını önlemek için çıkarma yerine uzay gemisi operatörünü<=> kullanın.

usort($array, function ($a, $b) {
    return $a['optionNumber'] <=> $b['optionNumber'];
});

1
Bu bana gerçekten yardımcı olmuyor çünkü kullanması için bir işlev sağlamamı gerektiriyor - ki bu benim kafamı
döndüremediğim

17
O sana kullanman için bir fonksiyon verdi. Ve istediğinizi yapmak için her zaman yerleşik bir işlev olmadığını kabul etmek zorunda kalacaksınız, bunu kendiniz yazmalısınız. Karşılaştırma işlevleri yalnızca iki öğenin sıralama düzenini gösteren 1, 0 veya -1 dönüşünü gerektirir.
Tesserex

1
Usort'a daha fazla baktım ve aslında oldukça havalı. Yukarıdakine basit bir karşılaştırma işlevi yazdım, ancak '==' seçeneğini kaçırdım. Yardımlar için teşekkürler çocuklar
Sjwdavies

3
Şimdi kapanış olarak da: - usort ($ dizi, işlev ($ a, $ b) {return $ b ["seçenekNumarası"] - $ a ["seçenekNumarası"];});
Joeri

1
@ KiloumapL'artélon Sonuç çıkarsa < 0, daha aönce görünmesi gereken sıralama işlevini belirtir b. Eğer öyleyse, > 0daha bönce görünmelidir a.
kennytm

57

kullanım usort

 usort($array, 'sortByOption');
 function sortByOption($a, $b) {
   return strcmp($a['optionNumber'], $b['optionNumber']);
 }

7
@BenSinclair, çünkü Kenny'nin çözümü sayılar için, bu çözüm dizeler için. Her ikisi de doğrudur :-) Bu alternatif için +1.
kubilay

Büyük / küçük harfe duyarsız sıralama için strcmp yerine
strcasecmp

dizide ikinci sıra için anahtar tanımlayabilir miyiz, ilk önce optionNumber ile sıralama sonra lastUpdated ile sıralama yapacağımız anlamına gelir. Bunu nasıl yapabilirim?
Bhavin Thummar

16

KennyTM ve AJ Quick'un her iki çözümünü de kullandım ve ASC veya DESC sıralama veya anahtarları koruma gibi birçok durumda veya dizinin alt öğeleri olarak nesneleriniz varsa bu konuda yardımcı olabilecek bir işlev buldum .

İşte bu işlev (uzay gemisi operatörü nedeniyle PHP7 ve üstü için çalışır):

/**
 * @param array $array
 * @param string $value
 * @param bool $asc - ASC (true) or DESC (false) sorting
 * @param bool $preserveKeys
 * @return array
 * */
function sortBySubValue($array, $value, $asc = true, $preserveKeys = false)
{
    if ($preserveKeys) {
        $c = [];
        if (is_object(reset($array))) {
            foreach ($array as $k => $v) {
                $b[$k] = strtolower($v->$value);
            }
        } else {
            foreach ($array as $k => $v) {
                $b[$k] = strtolower($v[$value]);
            }
        }
        $asc ? asort($b) : arsort($b);
        foreach ($b as $k => $v) {
            $c[$k] = $array[$k];
        }
        $array = $c;
    } else {
        if (is_object(reset($array))) {
            usort($array, function ($a, $b) use ($value, $asc) {
                return $a->{$value} == $b->{$value} ? 0 : ($a->{$value} <=> $b->{$value}) * ($asc ? 1 : -1);
            });
        } else {
            usort($array, function ($a, $b) use ($value, $asc) {
                return $a[$value] == $b[$value] ? 0 : ($a[$value] <=> $b[$value]) * ($asc ? 1 : -1);
            });
        }
    }

    return $array;
}

Kullanımı:

sortBySubValue($array, 'optionNumber', true, false);

Düzenle

İlk bölüm kullanılarak yeniden yazılabilir uasort()ve işlev daha kısa olacaktır (uzay gemisi operatörü nedeniyle PHP7 ve üstü için çalışır):

/**
 * @param array $array
 * @param string $value
 * @param bool $asc - ASC (true) or DESC (false) sorting
 * @param bool $preserveKeys
 * @return array
 * */
function sortBySubValue($array, $value, $asc = true, $preserveKeys = false)
{
    if (is_object(reset($array))) {
        $preserveKeys ? uasort($array, function ($a, $b) use ($value, $asc) {
            return $a->{$value} == $b->{$value} ? 0 : ($a->{$value} <=> $b->{$value}) * ($asc ? 1 : -1);
        }) : usort($array, function ($a, $b) use ($value, $asc) {
            return $a->{$value} == $b->{$value} ? 0 : ($a->{$value} <=> $b->{$value}) * ($asc ? 1 : -1);
        });
    } else {
        $preserveKeys ? uasort($array, function ($a, $b) use ($value, $asc) {
            return $a[$value] == $b[$value] ? 0 : ($a[$value] <=> $b[$value]) * ($asc ? 1 : -1);
        }) : usort($array, function ($a, $b) use ($value, $asc) {
            return $a[$value] == $b[$value] ? 0 : ($a[$value] <=> $b[$value]) * ($asc ? 1 : -1);
        });
    }
    return $array;
}

Buradaki en yararlı cevap bu, en üstte olmalı;)
Edi Budimilic

@EdiBudimilic teşekkürler, minnettarım! Bu arada cevabımı güncelledim ve bu işlevin daha kısa bir versiyonunu ekledim :)
Pigalev Pavel

1
Bunun benim için çalışmasını sağlamak için, dizeleri karşılaştırdığım için karşılaştırırken ve değerleri karşılaştırırken (eksi) >yerine (büyüktür) kullanmak zorunda kaldım . Yine de çalışıyor. -$a$b
James

1
@James haklısın. Cevabı değiştirdim ve uzay gemisi operatörü (<=>) kullanımını ekledim. Şimdi gayet iyi çalışmalı.
Pigalev Pavel

Bu durumu duyarsız hale getirmenin bir yolu var mı?
loeffel

4

Yukarıdakiler gibi bir işlev kullanılırken tuşlar kaldırılır. Anahtarlar önemliyse, aşağıdaki işlev onu koruyacaktır ... ancak foreach döngüleri oldukça verimsizdir.

function subval_sort($a,$subkey) {
    foreach($a as $k=>$v) {
        $b[$k] = strtolower($v[$subkey]);
    }
    asort($b);
    foreach($b as $key=>$val) {
        $c[$key] = $a[$key];
    }
    return $c;
}
$array = subval_sort($array,'optionNumber');

Yüksekten düşüğe doğru asort yerine arsort kullanın.

Kod kredisi: http://www.firsttube.com/read/sorting-a-multi-dimensional-array-with-php/


4

Array_multisort (), array_map () kullanma

array_multisort(array_map(function($element) {
      return $element['optionNumber'];
  }, $array), SORT_ASC, $array);

print_r($array);

DEMO


2
Bu çok kolay çalışıyor. Teşekkür ederim. Tek yapmam gereken sütun adımı değiştirmekti ve işe yaradı.
Kobus Myburgh

2
Bu aynı zamanda üst dizinin anahtarlarını da korur
JonnyS

3

PHP 5.3+

usort($array, function($a,$b){ return $a['optionNumber']-$b['optionNumber'];} );
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.