PHP Sắp xếp Mảng theo Giá trị Mảng Con


110

Tôi có cấu trúc mảng sau:

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

Cách tốt nhất để sắp xếp mảng theo cách tăng dần, dựa trên dấu optionNumber?

Vì vậy, kết quả như sau:

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

Câu trả lời:


204

Sử dụng usort.

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

...

usort($array, "cmp_by_optionNumber");

Trong PHP ≥5.3, bạn nên sử dụng một hàm ẩn danh để thay thế:

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

Lưu ý rằng cả hai mã trên đều giả sử $a['optionNumber']là một số nguyên. Sử dụng @St. Giải pháp của John Johnson nếu chúng là chuỗi.


Trong PHP ≥7.0, hãy sử dụng toán tử phi thuyền<=> thay vì phép trừ để ngăn chặn sự cố tràn / cắt bớt.

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

1
Điều đó không thực sự helpe tôi như usort đòi hỏi tôi cung cấp cho nó một chức năng để sử dụng - đó là chút khó khăn tôi không thể có được vòng đầu của tôi
Sjwdavies

17
Vâng, anh ấy chỉ cung cấp cho bạn chức năng để sử dụng. Và bạn sẽ phải chấp nhận rằng không phải lúc nào cũng có một chức năng tích hợp sẵn để làm những gì bạn muốn, bạn phải tự viết nó. Các hàm so sánh chỉ yêu cầu trả về 1, 0 hoặc -1 cho biết thứ tự sắp xếp cho hai phần tử.
Tesserex

1
Tôi đã xem xét thêm về cách sử dụng và nó thực sự khá tuyệt. Tôi đã viết một hàm so sánh đơn giản cho hàm ở trên, tuy nhiên đã bỏ sót '=='. Thanks for the guys giúp đỡ
Sjwdavies

3
Bây giờ cũng như là bao đóng: - usort ($ array, function ($ a, $ b) {return $ b ["optionNumber"] - $ a ["optionNumber"];});
Joeri

1
@ KiloumapL'artélon Nếu kết quả là < 0, nó cho biết hàm sắp xếp asẽ xuất hiện trước đó b. Nếu nó là > 0sau đó bsẽ xuất hiện trước a.
kennytm

57

Sử dụng usort

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

7
@BenSinclair, đó là vì giải pháp của Kenny là dành cho số, giải pháp này dành cho chuỗi. Cả hai đều đúng :-) +1 cho thay thế này.
kubilay

Đối với sắp xếp không phân biệt chữ hoa chữ thường, hãy sử dụng strcasecmp thay vì strcmp
user570605

chúng ta có thể xác định khóa cho thứ tự thứ hai trong mảng có nghĩa là chúng ta sắp xếp đầu tiên với optionNumber sau đó sắp xếp với lastUpdated. Làm thế nào có thể làm điều này?
Bhavin Thummar

16

Tôi đã sử dụng cả hai giải pháp của KennyTMAJ Quick và đưa ra một chức năng có thể trợ giúp trong vấn đề này trong nhiều trường hợp như sử dụng ASC hoặc DESC sắp xếp hoặc bảo toàn khóa hoặc nếu bạn có các đối tượng là con của mảng .

Đây là hàm này (hoạt động cho PHP7 trở lên vì toán tử tàu vũ trụ):

/**
 * @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;
}

Sử dụng:

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

Biên tập

Phần đầu tiên có thể được viết lại bằng cách sử dụng uasort()và hàm sẽ ngắn hơn (hoạt động cho PHP7 trở lên vì toán tử tàu vũ trụ):

/**
 * @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;
}

Đây là câu trả lời hữu ích nhất tốt nhất ở đây, nên trên đầu;)
Edi Budimilic

@EdiBudimilic cảm ơn bạn, tôi đánh giá cao điều đó! Bằng cách này tôi đã cập nhật câu trả lời của tôi và thêm một phiên bản ngắn hơn của chức năng này :)
Pigalev Pavel

1
Để làm cho điều này hoạt động cho tôi, tôi phải sử dụng >(lớn hơn) thay vì -(trừ) khi so sánh $a$bcác giá trị vì tôi đang so sánh các chuỗi. Vẫn hoạt động mặc dù.
James

1
@James bạn nói đúng. Tôi đã thay đổi câu trả lời và thêm việc sử dụng toán tử tàu vũ trụ (<=>). Bây giờ nó sẽ hoạt động tốt.
Pigalev Pavel 19/09/18

Có cách nào để làm cho trường hợp này không nhạy cảm không?
loeffel

4

Các phím được loại bỏ khi sử dụng một chức năng như các phím trên. Nếu các phím quan trọng, chức năng sau sẽ duy trì nó ... nhưng các vòng lặp foreach khá kém hiệu quả.

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

Sử dụng arsort thay vì asort nếu bạn muốn từ cao xuống thấp.

Mã tín dụng: http://www.firsttube.com/read/sorting-a-multi-dimensional-array-with-php/


4

Sử dụng array_multisort (), array_map ()

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

print_r($array);

BẢN GIỚI THIỆU


2
Điều này chỉ hoạt động rất dễ dàng. Cảm ơn bạn. Tất cả những gì tôi phải làm là thay đổi tên cột của mình và nó đã hoạt động.
Kobus Myburgh

2
Điều này cũng lưu giữ các khóa cho mảng mẹ
JonnyS

3

PHP 5.3+

usort($array, function($a,$b){ return $a['optionNumber']-$b['optionNumber'];} );
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.