尝试对PHP中的关联数组进行排序

时间:2018-10-27 15:04:16

标签: php arrays sorting associative-array

我正在尝试在PHP中对该关联数组进行排序,并按字段name

进行排序
$fonts = array(
    0 => ["index" => 0, "name" => "Arial", "path" => "assets/fonts/arial.ttf"],
    1 => ["index" => 1, "name" => "Times", "path" => "assets/fonts/times.ttf"],
    2 => ["index" => 2, "name" => "Roboto", "path" => "assets/fonts/roboto.ttf"],
    3 => ["index" => 3, "name" => "AlexBrush", "path" => "assets/fonts/AlexBrush-Regular.ttf"],
);

我想做的是按名称对条目进行排序,但保持与条目本身关联的键,所以我想要的是:

 $fonts = array(
    3 => ["index" => 3, "name" => "AlexBrush", "path" => "assets/fonts/AlexBrush-Regular.ttf"],
    0 => ["index" => 0, "name" => "Arial", "path" => "assets/fonts/arial.ttf"],
    2 => ["index" => 2, "name" => "Roboto", "path" => "assets/fonts/roboto.ttf"],
    1 => ["index" => 1, "name" => "Times", "path" => "assets/fonts/times.ttf"],
);

这是暴露问题的最低限度代码(PHP版本+7):

function cmp($a, $b)
{
    return strcmp($a["name"], $b["name"]);
}

$fonts = array(
    0 => ["index" => 0, "name" => "Arial", "path" => "assets/fonts/arial.ttf"],
    1 => ["index" => 1, "name" => "Times", "path" => "assets/fonts/times.ttf"],
    2 => ["index" => 2, "name" => "Roboto", "path" => "assets/fonts/roboto.ttf"],
    3 => ["index" => 3, "name" => "AlexBrush", "path" => "assets/fonts/AlexBrush-Regular.ttf"],
);

uasort($fonts, "cmp");

for($i = 0; $i < 4; $i++)
{
    echo "<br/>".$fonts[$i]["name"];
}

我正在使用uasort(),因为它应该在对数组进行排序时使键保持关联。不幸的是,如果我打印数组,则得到相同的顺序,即:

Arial
Times
Roboto
AlexBrush

4 个答案:

答案 0 :(得分:2)

name 的方式执行sort,并使用foreach()

循环
<?php

$fonts = array(
    0 => ["index" => 0, "name" => "Arial", "path" => "assets/fonts/arial.ttf"],
    1 => ["index" => 1, "name" => "Times", "path" => "assets/fonts/times.ttf"],
    2 => ["index" => 2, "name" => "Roboto", "path" => "assets/fonts/roboto.ttf"],
    3 => ["index" => 3, "name" => "AlexBrush", "path" => "assets/fonts/AlexBrush-Regular.ttf"],
);

uasort($fonts, function($a, $b) {
    return strcmp($a['name'], $b['name']);
});

print_r($fonts);

foreach($fonts as $font){
 echo $font["name"].PHP_EOL;
}

?>

编辑:基于OP的评论,

 $indexed_array = array_column($fonts,'name','index'); // array column map name by index
 print_r($indexed_array); 
 echo $indexed_array[3];

演示: https://3v4l.org/W7BOH

答案 1 :(得分:1)

正在使用...

for($i = 0; $i < 4; $i++)
{
    echo "<br/>".$fonts[$i]["name"];
}

要打印出这些值,您正在按数字顺序使用索引来显示它们。

如果您改为使用...

print_r($fonts);

您会看到它们已经排序并得到...

Array
(
    [3] => Array
        (
            [index] => 3
            [name] => AlexBrush
            [path] => assets/fonts/AlexBrush-Regular.ttf
        )

    [0] => Array
        (
            [index] => 0
            [name] => Arial
            [path] => assets/fonts/arial.ttf
        )

    [2] => Array
        (
            [index] => 2
            [name] => Roboto
            [path] => assets/fonts/roboto.ttf
        )

    [1] => Array
        (
            [index] => 1
            [name] => Times
            [path] => assets/fonts/times.ttf
        )

)

或者正如L. Faros在评论中指出的那样,如果您使用过...

foreach ( $fonts as $font ) {
    echo "<br/>".$font["name"];
}

你会得到

<br/>AlexBrush<br/>Arial<br/>Roboto<br/>Times

答案 2 :(得分:1)

您可以使用array_column使数组具有关联性,然后使用kso​​rt(键排序)进行排序。

from fly_app import app
import unittest

class FlaskTestCase(unittest.TestCase):

    def test_city_code(self):
        tester = app.test_client(self)
        response = tester.post('/flight_search/extensive', data=dict(origin="xxxx"))
        self.assertIn(b'That does not appear to be a valid city code', response.data)

    def test_code_pairs(self):
        tester = app.test_client(self)
        response = tester.post('/flight_search/extensive', data=dict(origin="HFD", destination="CAS"))
        self.assertIn(b'This origin-destination pair is not in searchable cache', response.data)

    def test_duration_range(self):
        tester = app.test_client(self)
        response = tester.post('/flight_search/extensive', data=dict(origin="MSP", destination="NYC", min_duration=20))
        self.assertIn(b'Number must be between 1 and 15', response.data)

    def test_duration_integer(self):
        tester = app.test_client(self)
        response = tester.post('/flight_search/extensive', data=dict(origin="MSP", destination="NYC", min_duration='abc'))
        self.assertIn(b'Not a valid integer value', response.data)

    def test_duration_pair(self):
        tester = app.test_client(self)
        response = tester.post('/flight_search/extensive', data=dict(origin="MSP", destination="NYC", min_duration=10, max_duration=7))
        self.assertIn(b'Maximum trip length cannot be less than minimum', response.data)

if __name__ == "__main__":
    unittest.main()

输出:

$fonts = array_column($fonts, null, "name");
ksort($fonts);
$fonts = array_values($fonts);
var_dump($fonts);

这意味着您可以像在问题中一样迭代数组。

https://3v4l.org/pJXfp


我看到您要求获得索引3名称。

在这种情况下,再次使用array_column使其与索引关联。

https://3v4l.org/nCtJf

array(4) {
  [0]=>
  array(3) {
    ["index"]=>
    int(3)
    ["name"]=>
    string(9) "AlexBrush"
    ["path"]=>
    string(34) "assets/fonts/AlexBrush-Regular.ttf"
  }
  [1]=>
  array(3) {
    ["index"]=>
    int(0)
    ["name"]=>
    string(5) "Arial"
    ["path"]=>
    string(22) "assets/fonts/arial.ttf"
  }
  [2]=>
  array(3) {
    ["index"]=>
    int(2)
    ["name"]=>
    string(6) "Roboto"
    ["path"]=>
    string(23) "assets/fonts/roboto.ttf"
  }
  [3]=>
  array(3) {
    ["index"]=>
    int(1)
    ["name"]=>
    string(5) "Times"
    ["path"]=>
    string(22) "assets/fonts/times.ttf"
  }
}

答案 3 :(得分:0)

如果您要继续使用repo1,则实际上需要重新索引第一级键-没什么大不了的,因为您仍然保留了for()中的原始数字ID。元素。

根据这种逻辑,我推荐两种不同的单线。

  1. index
  2. array_multisort(array_column($fonts, 'name'), $fonts);

Demo