2

私は、クライアントに対してマルチレベルの並べ替え(より適切な用語がないため、並べ替え内で並べ替え)を実行する関数に取り組んでいます。次のようなさまざまな属性を持つオブジェクトのリストがあるとします。

  • name-オブジェクトの名前
  • タイプ-オブジェクトタイプ
  • 日付-いくつかの日付属性

リストを最初に時系列で並べ替え、次にオブジェクトタイプで並べ替え、次にアルファベット順に並べ替えたいとしましょう。どうすればいいですか?

現在、usort()を使用して、上記の属性を異なる重みの整数に変換する独自の比較関数を渡しています。例えば。一次ソートが日付によるものである場合、それを整数に変換し、1000を乗算し、ソートの次の層を整数(この場合はタイプ)に変換し、100を乗算し、以下同様にすべてを加算します。オブジェクトが<または>別のものであるかどうかを判断するために一緒に。

もっとシンプルでエレガントな解決策はありますか?ありがとう

編集:明確にするために、すべてを「重み」に変換せずにマルチレベルの並べ替えを行うためのより良い方法はありますか?

4

1 に答える 1

4

基本的に、やりたいことは、一連の「短絡」比較を使用することです。上記の基準を考えると、単純な例は次のようになります (テストされていません)。

function mySort($a, $b) {
    if ($a->name < $b->name) {
        return -1;
    }

    if ($a->name > $b->name) {
        return 1;
    }

    // If we get this far, then name is equal, so
    // move on to checking type:
    if ($a->type < $b->type) {
        return -1;
    }

    if ($a->type > $b->type) {
        return 1;
    }

    // If we get this far, then both name and type are equal,
    // so move on to checking date:
    if ($a->date < $b->date) {
        return -1;
    }

    if ($a->date > $b->date) {
        return 1;
    }

    // If we get this far, then all three criteria are equal,
    // so for sorting purposes, these objects are considered equal.
    return 0;
}

ただし、前述したように、これは単純なソリューションであり、非常に拡張性がありません。ソートがソートメソッドにハードコーディングされていない、もう少し堅牢なソリューションを使用することをお勧めします。たとえば、次のアプローチを取ります (未テスト)。

// These are the properties to sort by, and the sort directions.
// They use PHP's native SORT_ASC and SORT_DESC constants.
$this->_sorts = [
    'name' => SORT_ASC,
    'type' => SORT_ASC,
    'date' => SORT_ASC
];

// Implemented as a class method this time.
protected function _mySort($a, $b) {
    foreach ($this->_sorts as $property => $direction) {
        if ($a->{$property} < $b->{$property}) {
            return $direction === SORT_ASC ? -1 : 1;
        }

        if ($a->{$property} > $b->{$property}) {
            return $direction === SORT_ASC ? 1 : -1;
        }
    }

    return 0;
}

現在、さまざまな並べ替えフィールドまたは並べ替え方向を追加または削除することは、配列要素を追加または変更するのと同じくらい簡単です。コードの変更は必要ありません。

于 2012-09-22T03:54:53.313 に答える