[PHP]sort関数を完全解説!配列を昇順にソートする方法

PHP

こんにちは!今回は、PHPの標準関数であるsort()について詳しく解説していきます。配列を昇順に並び替える最も基本的なソート関数です!

sort関数とは?

sort()関数は、配列を値の昇順に並び替える関数です。

元の配列を直接変更し(破壊的操作)、インデックスは0から振り直されます。数値、文字列、その他の型を自動的に判断してソートします!

基本的な構文

sort(array &$array, int $flags = SORT_REGULAR): bool
  • $array: ソートする配列(参照渡し)
  • $flags: ソート方法を指定するフラグ(オプション)
  • 戻り値: 成功時はtrue、失敗時はfalse

ソートフラグ

SORT_REGULAR      // 型を変換せずに比較(デフォルト)
SORT_NUMERIC      // 数値として比較
SORT_STRING       // 文字列として比較
SORT_LOCALE_STRING // 現在のロケールに基づいて文字列として比較
SORT_NATURAL      // 自然順ソート(natsort()と同じ)
SORT_FLAG_CASE    // SORT_STRING | SORT_FLAG_CASE で大文字小文字を区別しない

基本的な使用例

数値の配列をソート

// 数値の配列
$numbers = [5, 2, 8, 1, 9, 3];

sort($numbers);

print_r($numbers);
/*
Array (
    [0] => 1
    [1] => 2
    [2] => 3
    [3] => 5
    [4] => 8
    [5] => 9
)
*/

文字列の配列をソート

// 文字列の配列
$fruits = ['orange', 'apple', 'banana', 'grape'];

sort($fruits);

print_r($fruits);
/*
Array (
    [0] => apple
    [1] => banana
    [2] => grape
    [3] => orange
)
*/

インデックスの振り直し

// 連想配列のキーは失われる
$data = [
    'c' => 3,
    'a' => 1,
    'b' => 2
];

sort($data);

print_r($data);
/*
Array (
    [0] => 1
    [1] => 2
    [2] => 3
)
*/
// キー(c, a, b)は失われて0から振り直される

ソートフラグの使用

// 数値として比較
$mixed = ['10', '2', '1', '20'];

sort($mixed, SORT_NUMERIC);
print_r($mixed);
// Array ( [0] => 1 [1] => 2 [2] => 10 [3] => 20 )

// 文字列として比較
$mixed = ['10', '2', '1', '20'];
sort($mixed, SORT_STRING);
print_r($mixed);
// Array ( [0] => 1 [1] => 10 [2] => 2 [3] => 20 )

// 自然順ソート
$files = ['file10.txt', 'file2.txt', 'file1.txt', 'file20.txt'];
sort($files, SORT_NATURAL);
print_r($files);
// Array ( [0] => file1.txt [1] => file2.txt [2] => file10.txt [3] => file20.txt )

大文字小文字を区別しないソート

$words = ['Apple', 'banana', 'Cherry', 'apple'];

sort($words, SORT_STRING | SORT_FLAG_CASE);

print_r($words);
/*
Array (
    [0] => Apple
    [1] => apple
    [2] => banana
    [3] => Cherry
)
*/

実践的な使用例

例1: データソーター

class DataSorter {
    /**
     * 数値配列を昇順ソート
     */
    public static function sortNumbers($array) {
        sort($array, SORT_NUMERIC);
        return $array;
    }
    
    /**
     * 数値配列を降順ソート
     */
    public static function sortNumbersDescending($array) {
        rsort($array, SORT_NUMERIC);
        return $array;
    }
    
    /**
     * 文字列配列をソート
     */
    public static function sortStrings($array, $caseInsensitive = false) {
        $flags = $caseInsensitive ? 
            (SORT_STRING | SORT_FLAG_CASE) : 
            SORT_STRING;
        
        sort($array, $flags);
        return $array;
    }
    
    /**
     * 自然順ソート
     */
    public static function sortNatural($array) {
        sort($array, SORT_NATURAL);
        return $array;
    }
    
    /**
     * 混合型配列をソート
     */
    public static function sortMixed($array) {
        sort($array, SORT_REGULAR);
        return $array;
    }
    
    /**
     * ユニーク値を抽出してソート
     */
    public static function uniqueAndSort($array) {
        $unique = array_unique($array);
        sort($unique);
        return $unique;
    }
    
    /**
     * 配列をソートして最小値・最大値を取得
     */
    public static function getMinMax($array) {
        $sorted = self::sortNumbers($array);
        
        return [
            'min' => $sorted[0] ?? null,
            'max' => $sorted[count($sorted) - 1] ?? null,
            'sorted' => $sorted
        ];
    }
    
    /**
     * 中央値を取得(ソート後)
     */
    public static function getMedian($array) {
        $sorted = self::sortNumbers($array);
        $count = count($sorted);
        
        if ($count === 0) {
            return null;
        }
        
        $middle = floor($count / 2);
        
        if ($count % 2 === 0) {
            // 偶数の場合は中央2つの平均
            return ($sorted[$middle - 1] + $sorted[$middle]) / 2;
        } else {
            // 奇数の場合は中央の値
            return $sorted[$middle];
        }
    }
}

// 使用例
echo "=== データソート ===\n";

// 数値ソート
$numbers = [5, 2, 8, 1, 9, 3, 7, 4, 6];
echo "元の配列: " . implode(', ', $numbers) . "\n";
echo "昇順: " . implode(', ', DataSorter::sortNumbers($numbers)) . "\n";
echo "降順: " . implode(', ', DataSorter::sortNumbersDescending($numbers)) . "\n";

// 文字列ソート
echo "\n=== 文字列ソート ===\n";
$words = ['banana', 'Apple', 'cherry', 'apple'];
echo "元の配列: " . implode(', ', $words) . "\n";
echo "通常: " . implode(', ', DataSorter::sortStrings($words)) . "\n";
echo "大小無視: " . implode(', ', DataSorter::sortStrings($words, true)) . "\n";

// 自然順ソート
echo "\n=== 自然順ソート ===\n";
$files = ['file10.txt', 'file2.txt', 'file1.txt', 'file20.txt'];
echo "通常ソート: " . implode(', ', DataSorter::sortStrings($files)) . "\n";
echo "自然順: " . implode(', ', DataSorter::sortNatural($files)) . "\n";

// 最小値・最大値
echo "\n=== 最小値・最大値 ===\n";
$data = [45, 23, 89, 12, 67, 34];
$minMax = DataSorter::getMinMax($data);
echo "最小値: {$minMax['min']}\n";
echo "最大値: {$minMax['max']}\n";

// 中央値
echo "\n=== 中央値 ===\n";
$values = [1, 3, 5, 7, 9];
echo "中央値: " . DataSorter::getMedian($values) . "\n";

例2: 成績処理システム

class GradeProcessor {
    /**
     * 成績を昇順にソート
     */
    public static function sortGrades($grades) {
        sort($grades, SORT_NUMERIC);
        return $grades;
    }
    
    /**
     * ランキングを生成
     */
    public static function generateRanking($students) {
        // 成績のみを抽出
        $scores = [];
        foreach ($students as $student) {
            $scores[] = $student['score'];
        }
        
        // 降順にソート
        rsort($scores, SORT_NUMERIC);
        
        // ランキングマップを作成
        $ranking = [];
        $currentRank = 1;
        
        foreach ($scores as $index => $score) {
            if (!isset($ranking[$score])) {
                $ranking[$score] = $currentRank;
            }
            $currentRank++;
        }
        
        // 学生データにランキングを追加
        foreach ($students as &$student) {
            $student['rank'] = $ranking[$student['score']];
        }
        
        return $students;
    }
    
    /**
     * 成績を分類
     */
    public static function classifyGrades($grades) {
        $sorted = self::sortGrades($grades);
        
        return [
            'excellent' => array_filter($sorted, fn($g) => $g >= 90),
            'good' => array_filter($sorted, fn($g) => $g >= 70 && $g < 90),
            'average' => array_filter($sorted, fn($g) => $g >= 50 && $g < 70),
            'poor' => array_filter($sorted, fn($g) => $g < 50)
        ];
    }
    
    /**
     * 統計情報を取得
     */
    public static function getStatistics($grades) {
        $sorted = self::sortGrades($grades);
        $count = count($sorted);
        
        if ($count === 0) {
            return null;
        }
        
        return [
            'count' => $count,
            'min' => $sorted[0],
            'max' => $sorted[$count - 1],
            'average' => array_sum($sorted) / $count,
            'median' => DataSorter::getMedian($sorted),
            'sorted' => $sorted
        ];
    }
    
    /**
     * 上位N件を取得
     */
    public static function getTopN($grades, $n) {
        $sorted = self::sortGrades($grades);
        return array_slice(array_reverse($sorted), 0, $n);
    }
    
    /**
     * 下位N件を取得
     */
    public static function getBottomN($grades, $n) {
        $sorted = self::sortGrades($grades);
        return array_slice($sorted, 0, $n);
    }
}

// 使用例
echo "=== 成績処理システム ===\n";

$grades = [85, 92, 78, 65, 88, 95, 72, 80, 90, 68];

// 統計情報
$stats = GradeProcessor::getStatistics($grades);
echo "統計情報:\n";
echo "  件数: {$stats['count']}\n";
echo "  最低点: {$stats['min']}\n";
echo "  最高点: {$stats['max']}\n";
echo "  平均点: " . round($stats['average'], 2) . "\n";
echo "  中央値: {$stats['median']}\n";

// 成績分類
echo "\n=== 成績分類 ===\n";
$classified = GradeProcessor::classifyGrades($grades);
foreach ($classified as $category => $scores) {
    echo "{$category}: " . implode(', ', $scores) . "\n";
}

// 上位・下位
echo "\n=== 上位・下位 ===\n";
echo "上位3件: " . implode(', ', GradeProcessor::getTopN($grades, 3)) . "\n";
echo "下位3件: " . implode(', ', GradeProcessor::getBottomN($grades, 3)) . "\n";

// ランキング
echo "\n=== ランキング ===\n";
$students = [
    ['name' => 'Alice', 'score' => 85],
    ['name' => 'Bob', 'score' => 92],
    ['name' => 'Charlie', 'score' => 78],
    ['name' => 'David', 'score' => 92],
    ['name' => 'Eve', 'score' => 88]
];

$ranked = GradeProcessor::generateRanking($students);
foreach ($ranked as $student) {
    echo "{$student['rank']}位: {$student['name']} ({$student['score']}点)\n";
}

例3: 在庫管理システム

class InventoryManager {
    /**
     * 在庫数でソート
     */
    public static function sortByQuantity($items) {
        $quantities = array_column($items, 'quantity');
        array_multisort($quantities, SORT_ASC, $items);
        return $items;
    }
    
    /**
     * 価格でソート
     */
    public static function sortByPrice($items) {
        $prices = array_column($items, 'price');
        array_multisort($prices, SORT_ASC, $items);
        return $items;
    }
    
    /**
     * 在庫切れ・少量在庫を抽出
     */
    public static function getLowStock($items, $threshold = 10) {
        $lowStock = array_filter($items, function($item) use ($threshold) {
            return $item['quantity'] <= $threshold;
        });
        
        return self::sortByQuantity(array_values($lowStock));
    }
    
    /**
     * 商品名でソート
     */
    public static function sortByName($items) {
        $names = array_column($items, 'name');
        array_multisort($names, SORT_ASC, SORT_STRING, $items);
        return $items;
    }
    
    /**
     * カテゴリ別にグループ化してソート
     */
    public static function groupByCategory($items) {
        $grouped = [];
        
        foreach ($items as $item) {
            $category = $item['category'];
            
            if (!isset($grouped[$category])) {
                $grouped[$category] = [];
            }
            
            $grouped[$category][] = $item;
        }
        
        // カテゴリ名でソート
        ksort($grouped);
        
        // 各カテゴリ内を商品名でソート
        foreach ($grouped as &$categoryItems) {
            $categoryItems = self::sortByName($categoryItems);
        }
        
        return $grouped;
    }
    
    /**
     * 在庫総額を計算
     */
    public static function calculateTotalValue($items) {
        $total = 0;
        
        foreach ($items as $item) {
            $total += $item['price'] * $item['quantity'];
        }
        
        return $total;
    }
}

// 使用例
echo "=== 在庫管理システム ===\n";

$inventory = [
    ['name' => 'りんご', 'category' => '果物', 'price' => 100, 'quantity' => 50],
    ['name' => 'バナナ', 'category' => '果物', 'price' => 80, 'quantity' => 5],
    ['name' => 'にんじん', 'category' => '野菜', 'price' => 60, 'quantity' => 30],
    ['name' => 'じゃがいも', 'category' => '野菜', 'price' => 50, 'quantity' => 3],
    ['name' => 'トマト', 'category' => '野菜', 'price' => 120, 'quantity' => 25]
];

// 在庫数でソート
echo "在庫数順:\n";
$sorted = InventoryManager::sortByQuantity($inventory);
foreach ($sorted as $item) {
    echo "  {$item['name']}: {$item['quantity']}個\n";
}

// 価格でソート
echo "\n価格順:\n";
$sorted = InventoryManager::sortByPrice($inventory);
foreach ($sorted as $item) {
    echo "  {$item['name']}: {$item['price']}円\n";
}

// 在庫少量商品
echo "\n在庫少量商品(10個以下):\n";
$lowStock = InventoryManager::getLowStock($inventory, 10);
foreach ($lowStock as $item) {
    echo "  {$item['name']}: {$item['quantity']}個(要補充)\n";
}

// カテゴリ別
echo "\nカテゴリ別:\n";
$grouped = InventoryManager::groupByCategory($inventory);
foreach ($grouped as $category => $items) {
    echo "\n{$category}:\n";
    foreach ($items as $item) {
        echo "  - {$item['name']} ({$item['quantity']}個, {$item['price']}円)\n";
    }
}

// 在庫総額
echo "\n在庫総額: " . number_format(InventoryManager::calculateTotalValue($inventory)) . "円\n";

例4: ファイル管理システム

class FileManager {
    /**
     * ファイル名をソート
     */
    public static function sortByName($files) {
        sort($files, SORT_STRING);
        return $files;
    }
    
    /**
     * ファイル名を自然順でソート
     */
    public static function sortNatural($files) {
        sort($files, SORT_NATURAL);
        return $files;
    }
    
    /**
     * ファイルサイズでソート
     */
    public static function sortBySize($files) {
        $sizes = [];
        
        foreach ($files as $file) {
            $sizes[] = file_exists($file) ? filesize($file) : 0;
        }
        
        array_multisort($sizes, SORT_ASC, $files);
        return $files;
    }
    
    /**
     * 更新日時でソート
     */
    public static function sortByModifiedTime($files) {
        $times = [];
        
        foreach ($files as $file) {
            $times[] = file_exists($file) ? filemtime($file) : 0;
        }
        
        array_multisort($times, SORT_ASC, $files);
        return $files;
    }
    
    /**
     * 拡張子でグループ化
     */
    public static function groupByExtension($files) {
        $grouped = [];
        
        foreach ($files as $file) {
            $ext = pathinfo($file, PATHINFO_EXTENSION);
            $ext = $ext ?: 'no_extension';
            
            if (!isset($grouped[$ext])) {
                $grouped[$ext] = [];
            }
            
            $grouped[$ext][] = $file;
        }
        
        // 拡張子でソート
        ksort($grouped);
        
        // 各グループ内をファイル名でソート
        foreach ($grouped as &$group) {
            $group = self::sortNatural($group);
        }
        
        return $grouped;
    }
    
    /**
     * ディレクトリ内のファイルをソート
     */
    public static function listSorted($directory, $sortBy = 'name') {
        $files = glob($directory . '/*');
        
        switch ($sortBy) {
            case 'size':
                return self::sortBySize($files);
            case 'date':
                return self::sortByModifiedTime($files);
            case 'natural':
                return self::sortNatural($files);
            default:
                return self::sortByName($files);
        }
    }
}

// 使用例
echo "=== ファイル管理システム ===\n";

$files = [
    'file10.txt',
    'file2.txt',
    'file1.txt',
    'file20.txt',
    'document.pdf',
    'image.jpg',
    'script.php'
];

// 通常のソート
echo "通常ソート:\n";
$sorted = FileManager::sortByName($files);
foreach ($sorted as $file) {
    echo "  {$file}\n";
}

// 自然順ソート
echo "\n自然順ソート:\n";
$sorted = FileManager::sortNatural($files);
foreach ($sorted as $file) {
    echo "  {$file}\n";
}

// 拡張子でグループ化
echo "\n拡張子別:\n";
$grouped = FileManager::groupByExtension($files);
foreach ($grouped as $ext => $fileList) {
    echo "\n.{$ext}:\n";
    foreach ($fileList as $file) {
        echo "  - {$file}\n";
    }
}

例5: タグ・キーワード管理

class TagManager {
    /**
     * タグをソート(重複除去)
     */
    public static function sortTags($tags, $caseInsensitive = true) {
        // 重複除去
        $tags = array_unique($tags);
        
        // ソート
        if ($caseInsensitive) {
            sort($tags, SORT_STRING | SORT_FLAG_CASE);
        } else {
            sort($tags, SORT_STRING);
        }
        
        return array_values($tags);
    }
    
    /**
     * タグを頻度順にソート
     */
    public static function sortByFrequency($tags) {
        $frequency = array_count_values($tags);
        arsort($frequency);
        
        return array_keys($frequency);
    }
    
    /**
     * タグを正規化してソート
     */
    public static function normalizeAndSort($tags) {
        // 正規化(小文字化、トリム)
        $normalized = array_map(function($tag) {
            return strtolower(trim($tag));
        }, $tags);
        
        // 重複除去とソート
        return self::sortTags($normalized);
    }
    
    /**
     * 人気タグを取得
     */
    public static function getPopularTags($tags, $limit = 10) {
        $sorted = self::sortByFrequency($tags);
        return array_slice($sorted, 0, $limit);
    }
    
    /**
     * タグクラウド用データを生成
     */
    public static function generateTagCloud($tags) {
        $frequency = array_count_values($tags);
        $sorted = self::sortTags(array_keys($frequency));
        
        $cloud = [];
        foreach ($sorted as $tag) {
            $cloud[] = [
                'tag' => $tag,
                'count' => $frequency[$tag],
                'weight' => self::calculateWeight($frequency[$tag], $frequency)
            ];
        }
        
        return $cloud;
    }
    
    /**
     * タグの重み(サイズ)を計算
     */
    private static function calculateWeight($count, $allCounts) {
        $min = min($allCounts);
        $max = max($allCounts);
        
        if ($max === $min) {
            return 50;
        }
        
        // 10-100の範囲に正規化
        return 10 + (($count - $min) / ($max - $min)) * 90;
    }
}

// 使用例
echo "=== タグ管理 ===\n";

$tags = [
    'PHP', 'JavaScript', 'php', 'Python', 'PHP',
    'JavaScript', 'Ruby', 'Go', 'PHP', 'Java',
    'JavaScript', 'PHP', 'TypeScript'
];

// タグをソート
echo "ソート済みタグ:\n";
$sorted = TagManager::sortTags($tags);
echo "  " . implode(', ', $sorted) . "\n";

// 頻度順
echo "\n頻度順:\n";
$byFrequency = TagManager::sortByFrequency($tags);
foreach ($byFrequency as $tag) {
    $count = count(array_filter($tags, fn($t) => strtolower($t) === strtolower($tag)));
    echo "  {$tag}: {$count}回\n";
}

// 人気タグ
echo "\n人気タグ(上位5件):\n";
$popular = TagManager::getPopularTags($tags, 5);
echo "  " . implode(', ', $popular) . "\n";

// タグクラウド
echo "\nタグクラウドデータ:\n";
$cloud = TagManager::generateTagCloud($tags);
foreach ($cloud as $item) {
    echo "  {$item['tag']}: {$item['count']}回 (重み: " . round($item['weight']) . ")\n";
}

例6: 検索結果のソート

class SearchResultSorter {
    /**
     * スコアでソート
     */
    public static function sortByRelevance($results) {
        $scores = array_column($results, 'score');
        array_multisort($scores, SORT_DESC, $results);
        return $results;
    }
    
    /**
     * 日付でソート(新しい順)
     */
    public static function sortByDate($results) {
        $dates = array_column($results, 'date');
        array_multisort($dates, SORT_DESC, $results);
        return $results;
    }
    
    /**
     * タイトルでソート
     */
    public static function sortByTitle($results) {
        $titles = array_column($results, 'title');
        array_multisort($titles, SORT_ASC, SORT_STRING, $results);
        return $results;
    }
    
    /**
     * 複合ソート(スコア→日付)
     */
    public static function sortByRelevanceAndDate($results) {
        $scores = array_column($results, 'score');
        $dates = array_column($results, 'date');
        
        array_multisort(
            $scores, SORT_DESC,
            $dates, SORT_DESC,
            $results
        );
        
        return $results;
    }
    
    /**
     * ページネーション用に分割
     */
    public static function paginate($results, $page = 1, $perPage = 10) {
        $offset = ($page - 1) * $perPage;
        
        return [
            'results' => array_slice($results, $offset, $perPage),
            'total' => count($results),
            'page' => $page,
            'per_page' => $perPage,
            'total_pages' => ceil(count($results) / $perPage)
        ];
    }
}

// 使用例
echo "=== 検索結果ソート ===\n";

$searchResults = [
    ['title' => '記事A', 'score' => 0.9, 'date' => '2026-03-20'],
    ['title' => '記事B', 'score' => 0.7, 'date' => '2026-03-22'],
    ['title' => '記事C', 'score' => 0.9, 'date' => '2026-03-21'],
    ['title' => '記事D', 'score' => 0.5, 'date' => '2026-03-23'],
];

// 関連度順
echo "関連度順:\n";
$sorted = SearchResultSorter::sortByRelevance($searchResults);
foreach ($sorted as $result) {
    echo "  {$result['title']} (スコア: {$result['score']})\n";
}

// 日付順
echo "\n日付順(新しい順):\n";
$sorted = SearchResultSorter::sortByDate($searchResults);
foreach ($sorted as $result) {
    echo "  {$result['title']} ({$result['date']})\n";
}

// 複合ソート
echo "\n関連度→日付順:\n";
$sorted = SearchResultSorter::sortByRelevanceAndDate($searchResults);
foreach ($sorted as $result) {
    echo "  {$result['title']} (スコア: {$result['score']}, 日付: {$result['date']})\n";
}

他のソート関数との比較

$array = ['c' => 3, 'a' => 1, 'b' => 2];

// sort() - 値でソート、キーを失う
$sorted = $array;
sort($sorted);
print_r($sorted);
// Array ( [0] => 1 [1] => 2 [2] => 3 )

// asort() - 値でソート、キーを保持
$sorted = $array;
asort($sorted);
print_r($sorted);
// Array ( [a] => 1 [b] => 2 [c] => 3 )

// ksort() - キーでソート
$sorted = $array;
ksort($sorted);
print_r($sorted);
// Array ( [a] => 1 [b] => 2 [c] => 3 )

// rsort() - 降順ソート
$sorted = $array;
rsort($sorted);
print_r($sorted);
// Array ( [0] => 3 [1] => 2 [2] => 1 )

まとめ

sort()関数の特徴をまとめると:

できること:

  • 配列を値の昇順にソート
  • 数値・文字列・混合型に対応
  • 様々なソートフラグで動作調整

推奨される使用場面:

  • 単純な配列のソート
  • 数値データの並び替え
  • 文字列リストの整列
  • ランキング生成

ソートフラグ:

  • SORT_REGULAR: デフォルト
  • SORT_NUMERIC: 数値として比較
  • SORT_STRING: 文字列として比較
  • SORT_NATURAL: 自然順ソート
  • SORT_FLAG_CASE: 大文字小文字無視

注意点:

  • 元の配列を直接変更(破壊的)
  • キーは0から振り直される
  • 連想配列のキーは失われる

関連関数:

  • rsort(): 降順ソート
  • asort(): キーを保持してソート
  • ksort(): キーでソート
  • usort(): ユーザー定義関数でソート
  • natsort(): 自然順ソート

使い分け:

// 単純な配列のソート
sort($array);

// キーを保持
asort($array);

// 降順
rsort($array);

// 自然順
sort($array, SORT_NATURAL);

sort()は、PHPで最も基本的なソート関数です。配列を昇順に並び替える際は、この関数からスタートしましょう!

タイトルとURLをコピーしました