自定义按最高值对n个项目进行多维排序

时间:2019-04-17 05:20:47

标签: php arrays sorting

我目前能够使用自定义排序方法对多维数组进行排序。每个数组lineupSet都有n个项目。函数sort_points将对每个lineupSet从最高totalPoints到最低lineupSet进行排序,然后它将给我totalPoints,其总lineupSet最高。我目前正在改变方法,我仍然想先对每个totalPoints进行排序,并按从高到低的顺序排序。然后,我想根据给定的计数获得每个lineupSet中最高的$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]);

排序功能

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
                        )

                )

        )

)

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

n

我想对最高totalPoints最高的n做同样的事情。请记住,有时每个lineupSet中的totalPoints个项目中import matplotlib.pyplot as plt import numpy as np label = [r'$\mathregular{PM_{2.5}}$','OC',r'$\mathregular{SO_4^{2-}}$',\ r'$\mathregular{NH_4^{+}}$', r'$\mathregular{NO_3^{-}}$', \ "EC",r'$\mathregular{Cl^{-}}$','K','Al','Ca','Fe','Na','Mg','Zn','Pb','Ti','Ba','Mn','Cu'] fig = plt.figure(figsize=(9,2)) ax = plt.subplot(111) pos = np.arange(0,len(label),1) ax.set_xlim(0-0.5,pos[-1]+0.5) ax.set_xticks(pos) ax.set_xticklabels(label, fontsize = 12) plt.tight_layout() plt.show() 最高。

4 个答案:

答案 0 :(得分:5)

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

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

答案 1 :(得分:1)

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

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

* i我假设我们不在乎复杂性,在现实生活中(在本例中为我的生活),也没有需要在多维数组中进行排序的情况,因为数组只是要保留的存储空间数据可以被人类读取。


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

答案 2 :(得分:0)

检查一下

$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 :(得分:0)

看起来您想查找按降序排列的前2个条目。您可以简单地遍历包含formula键的所有条目,然后将它们添加到数组中,然后对其进行排序:

$pointsArray = array();
foreach ($testArray as $array1) {
    foreach ($array1["lineupSet"] as $array2) {
        if (isset($array2["formula"])) {
            $pointsArray[] = $array2;
        } else {
            foreach ($array2 as $array3) {
                $pointsArray[] = $array3;
            }
        }
    }
}
usort($pointsArray, function($item1, $item2) {
    $points1 = $item1["formula"]["totalPoints"];
    $points2 = $item2["formula"]["totalPoints"];
    return $points1 > $points2 ? -1 : ($points1 < $points2 ? 1 : 0);
});
$pointsArray = array_slice($pointsArray, 0, 2); // top 2 items
var_dump($pointsArray); // or array(array("lineupSet" => $pointsArray))

输出:

array(2) {
  [0]=>
  array(2) {
    ["formula"]=>
    array(1) {
      ["totalPoints"]=>
      float(220.66)
    }
    ["name"]=>
    string(10) "arr1-test1"
  }
  [1]=>
  array(2) {
    ["formula"]=>
    array(1) {
      ["totalPoints"]=>
      float(214.76)
    }
    ["name"]=>
    string(10) "arr1-test0"
  }
}