【问题标题】:Custom sorting multidimensional with n items by highest value自定义排序多维与 n 项最高值
【发布时间】:2019-04-17 05:20:47
【问题描述】:

我目前能够使用自定义排序方法对多维数组进行排序。每个数组lineupSet 有一个n 数量的项目。函数sort_points 将每个lineupSet 从最高到最低totalPoints 排序,然后它会给我lineupSet 和最高总数totalPoints。我目前正在改变方法,我仍然想先对每个lineupSet 进行排序,然后从高到低排序。然后我想根据给定的计数获得每个lineupSet 中最高的totalPoints。解决这个问题的最佳方法是什么?

测试数组:

$testArray = [[
    "lineupSet" => [
        [[
            "formula" => [
                "totalPoints" => 214.61,
            ],
            "name"    => "arr0-test0",
        ], [
            "formula" => [
                "totalPoints" => 201.17,
            ],
            "name"    => "arr0-test1",
        ]], [
            "formula" => [
                "totalPoints" => 5.01,
            ],
            "name"    => "arr0-test2",
        ]],
], [
    "lineupSet" => [
        [[
            "formula" => [
                "totalPoints" => 214.76,
            ],
            "name"    => "arr1-test0",
        ], [
            "formula" => [
                "totalPoints" => 220.66,
            ],
            "name"    => "arr1-test1",
        ]],
    ],
], [
    "lineupSet" => [
        [[
            "formula" => [
                "totalPoints" => 205.71,
            ],
            "name"    => "arr2-test0",
        ], [
            "formula" => [
                "totalPoints" => 204.43,
            ],
            "name"    => "arr2-test1",
        ]],
    ],
], [
    "lineupSet" => [
        [[
            "formula" => [
                "totalPoints" => 205.48,
            ],
            "name"    => "arr3-test0",
        ], [
            "formula" => [
                "totalPoints" => 203.51,
            ],
            "name"    => "arr3-test1",
        ]],
    ],
]];

排序功能

function sum_points($v) {
    $totalPoints = 0;
    foreach ($v['lineupSet'] as $lset) {
        if (isset($lset['formula'])) {
            $totalPoints += $lset['formula']['totalPoints'];
        }
        else {
            foreach ($lset as $l) {
                $totalPoints += $l['formula']['totalPoints'];
            }
        }
    }
    return $totalPoints;
}

function sort_points($a, $b) {
    return sum_points($b) - sum_points($a);
}

usort($testArray, 'sort_points');
print_r($testArray[0]);

例如,我想获得前两个最高的“totalPoints”。期望的结果:

Array (
    [lineupSet] => Array
        (
            [0] => Array
                (
                    [0] => Array
                        (
                            [formula] => Array
                                (
                                    [totalPoints] => 220.66
                                )

                            [name] => arr1-test1
                        )

                    [1] => Array
                        (
                            [formula] => Array
                                (
                                    [totalPoints] => 214.76
                                )

                            [name] => arr0-test0
                        )

                )

        )

)

我想对最高的n 最高的totalPoints 做同样的事情。请记住,有时必须从每个lineupSet 中提取最高totalPointsn 项目。

【问题讨论】:

  • 您所做的不仅仅是排序,而是在减少。出于这个原因,我会使用array_reduce。也可以将其视为两个单独的排序操作,内部数组和外部数组。
  • @Ultimater 这是一个很好的观点。我以前没有和array_reduce 合作过。你能告诉我如何应用这些方法吗?
  • 第二个条目实际上应该是 214.76(totalPoints 从排序最高的lineupSet 中的第二个条目开始)?
  • @Nick,你是对的。我复制粘贴不正确。
  • 我认为你需要在每个数组和每个子数组上循环以获得每个数组的总结果

标签: php arrays sorting


【解决方案1】:

我认为最好使用对象,然后在对数据进行排序时保持最大值(也可以使用构造函数对数组进行排序)。

Class SortHelper{
    public $max = 0;

    private function checkMax($totalPoints){
        if($totalPoints > $this->max)
            $this->max = $totalPoints;
    }

    private function sum_points($v) {
        $totalPoints = 0;
        foreach ($v['lineupSet'] as $lset) {
            if (isset($lset['formula'])) {
                $totalPoints += $lset['formula']['totalPoints'];
                $this->checkMax($lset['formula']['totalPoints']);
            }
            else {
                foreach ($lset as $l) {
                    $totalPoints += $l['formula']['totalPoints'];
                    $this->checkMax($l['formula']['totalPoints']);
                }
            }
        }
        return $totalPoints;
    }

    private function sort_points($a, $b) {
        return $this->sum_points($b) - $this->sum_points($a);
    }

    public function sort($array){
        usort( $array, [$this, 'sort_points']); 
        return $array;
    }
}

那么你会:

$sortHelper = new SortHelper();
$sorted_array = $sortHelper->sort($testArray);

var_dump($sorted_array[0]);
var_dump($sortHelper->max);

【讨论】:

  • 这看起来是一种让 OP 更接近解决方案的好方法。
【解决方案2】:

看看这个,

$n = 2; // number of elements 

$testArray = [[
    "lineupSet" => [
        [[
            "formula" => [
                "totalPoints" => 214.61,
            ],
            "name"    => "arr0-test0",
        ], [
            "formula" => [
                "totalPoints" => 201.17,
            ],
            "name"    => "arr0-test1",
        ]], [
            "formula" => [
                "totalPoints" => 5.01,
            ],
            "name"    => "arr0-test2",
        ]
    ],
], [
    "lineupSet" => [
        [[
            "formula" => [
                "totalPoints" => 214.76,
            ],
            "name"    => "arr1-test0",
        ], [
            "formula" => [
                "totalPoints" => 220.66,
            ],
            "name"    => "arr1-test1",
        ]],
    ],
], [
    "lineupSet" => [
        [[
            "formula" => [
                "totalPoints" => 205.71,
            ],
            "name"    => "arr2-test0",
        ], [
            "formula" => [
                "totalPoints" => 204.43,
            ],
            "name"    => "arr2-test1",
        ]],
    ],
], [
    "lineupSet" => [
        [[
            "formula" => [
                "totalPoints" => 205.48,
            ],
            "name"    => "arr3-test0",
        ], [
            "formula" => [
                "totalPoints" => 203.51,
            ],
            "name"    => "arr3-test1",
        ]],
    ],
]];

function sort_points($a, $b)
{
    return ($a['formula']['totalPoints'] > $b['formula']['totalPoints']) ? -1 : 1;
}

$result = [];

$reference = &$result['lineupSet'][0]; // store reference in $reference

foreach ($testArray as $tA) {
    foreach ($tA['lineupSet'] as $t) {
        foreach ($t as $child) {
            $reference[] = $child;
        }
    }
}

usort($reference, 'sort_points');
$reference = array_slice($reference, 0, $n);
var_dump($result); // desired output

【讨论】:

    【解决方案3】:

    请试试这2个功能,步骤如下:

    1. sort_points(); 使用 arsort PHP 函数对其进行排序并将其返回到新的简化数组。
    2. transform_arrays($sortedArray, $testArray); $testArray 将被 sortedArray 改变值。
    3. 将所有代码复制到.php的单个文件中并运行它。

    *我假设我们不关心复杂性,在现实生活中(在这种情况下是我的生活)没有什么需要在多维数组中排序的情况,因为数组只是要保留的存储数据可以被人类读取。


    <?php
    
    $testArray = 
        [
            ['lineupSet' => [[['formula' => ['totalPoints' => 214.61],'name' => 'arr0-test0'],['formula' => ['totalPoints' => 220.66],'name' => 'arr1-test1']]]],
            ['lineupSet' => [[['formula' => ['totalPoints' => 205.71],'name' => 'arr2-test0'],['formula' => ['totalPoints' => 204.43],'name' => 'arr2-test1']]]],
            ['lineupSet' => [[['formula' => ['totalPoints' => 205.48],'name' => 'arr3-test0'],['formula' => ['totalPoints' => 203.51],'name' => 'arr3-test1']]]]
        ];
    
    // sort into another array
    function sort_points($testArray = []){
        $response = $result = [];
        $i = 0;
        foreach($testArray as $array2){
            foreach($array2['lineupSet'][0] as $item){
               $result[$item['name']] = $item['formula']['totalPoints'];
               $i++;
            }
        }
        arsort($result);
    
        $i = 0;
        foreach($result as $key => $val){
            $response[$i]['name'] = $key;
            $response[$i]['totalPoints'] = $val;
            $i++;
        }
        return $response;
    }
    
    // this won't work if the $testArray format structure is changed
    function transform_arrays($items, $testArray){
    
        $l = 0;
        for($i=0;$i<count($testArray);$i++){
            for($j=0;$j<count($testArray[$i]);$j++){
                for($k=0;$k<count($testArray[$i]['lineupSet'][$j]);$k++){
                    $testArray[$i]['lineupSet'][$j][$k]['formula']['totalPoints'] = $items[$l]['totalPoints'];
                    $testArray[$i]['lineupSet'][$j][$k]['name'] = $items[$l]['name'];
                    // print_r($testArray[$i]['lineupSet'][$j][$k]['formula']['totalPoints']);
                    // print_r($testArray[$i]['lineupSet'][$j][$k]);
                    $l++;
                }
    
            }
        }
        return $testArray;
    }
    
    echo '<pre>';
    $sortedArray = sort_points($testArray);
    $response = transform_arrays($sortedArray, $testArray);
    print_r($response);
    echo '</pre>';
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-04-19
      • 1970-01-01
      • 2020-03-19
      • 2017-06-08
      • 1970-01-01
      • 2014-04-01
      • 2020-05-27
      相关资源
      最近更新 更多