Sort a multidimensional array by one column, keeping the same array rows

4

I have an array with two columns, where in the first column I have the name of a station, and in the second I have the address of the station.

I need to sort this array in alphabetical order of the station name, without losing the associated address!

I tried the array_multisort() function, but I can only sort the columns separately. Can you help me?

This was the code used, based on the array_multisort() function documentation. It returns the "$ data" vector still out of order, and the "$ sites" and "$ IPs" vectors are empty.

            $data = array( 'sites' => $lista_estacoes, 'IPs' => $lista_enderecos);

            foreach ($data as $key => $row) {
                    $sites[$key] = $row['sites'];
                    $IPs[$key] = $row['IPs'];
            }

            array_multisort($sites, SORT_DESC, $IPs, SORT_ASC, $data);

Where " $lista_estacoes " and " $lista_enderecos " are the vectors containing the data of the stations. Any mistakes I'm not aware of?

The array " $data " looks like this:

 Array
 (
     [sites] => Array
         (
        [0] => 

        [1] => PrimeiraEstacao

        [2] => SegundaEstacao

        [3] => TerceiraEstacao

        [4] => 

        [5] => QuintaEstacao

...
         )

     [IPs] => Array
         (
        [0] => 

        [1] => 172.168.0.11

        [2] => 172.168.0.12

        [3] => 172.168.0.13

        [4] => 172.168.0.14

        [5] => 172.168.0.15

...
         )
 )
    
asked by anonymous 29.06.2015 / 15:29

4 answers

1

One possible solution is to group the values two by two before ordering:

$arr = array_map(null, $arr["sites"], $arr["IPs"]);

Do the ordering according to the zero index, referring to the sites column:

usort($arr, function ($a, $b) {
    return strcmp($a[0], $b[0]);
});

Then, return the list of values by separating the pairs using array_column :

return [
    "sites" => array_column($arr, 0),
    "IPs"   => array_column($arr, 1)
];

That is, the function that does the desired sort would be:

function order ($arr)
{
    $arr = array_map(null, $arr["sites"], $arr["IPs"]);

    usort($arr, function ($a, $b) {
        return strcmp($a[0], $b[0]);
    });

    return [
        "sites" => array_column($arr, 0),
        "IPs"   => array_column($arr, 1)
    ];
}

For a test entry equal to:

$data = Array(
    'sites' => Array(
        0 => '',
        1 => '5 Estacao',
        2 => '3 Estacao',
        3 => '4 Estacao',
        4 => '1 Estacao',
        5 => '2 Estacao',
    ),
    'IPs' => Array(
        0 => '',
        1 => '172.168.0.15',
        2 => '172.168.0.13',
        3 => '172.168.0.14',
        4 => '172.168.0.11',
        5 => '172.168.0.12',
    )
);

The output generated by print_r(order($data)) will be:

Array
(
    [sites] => Array
        (
            [0] => 
            [1] => 1 Estacao
            [2] => 2 Estacao
            [3] => 3 Estacao
            [4] => 4 Estacao
            [5] => 5 Estacao
        )

    [IPs] => Array
        (
            [0] => 
            [1] => 172.168.0.11
            [2] => 172.168.0.12
            [3] => 172.168.0.13
            [4] => 172.168.0.14
            [5] => 172.168.0.15
        )
)

What exactly is the entry list, sorted by site name, without losing the order of the IPs.

  

See working at Ideone .

    
21.06.2017 / 13:52
0
$arrayTeste = Array(
    'sites' => Array(
        0 => '',
        1 => '5 Estacao',
        2 => '3 Estacao',
        3 => '4 Estacao',
        4 => '1 Estacao',
        5 => '2 Estacao',
    ),
    'IPs' => Array(
        0 => '',
        1 => '172.168.0.15',
        2 => '172.168.0.13',
        3 => '172.168.0.14',
        4 => '172.168.0.11',
        5 => '172.168.0.12',
    )
);

First I suggest unifying the data:

$newArray = array();
foreach ($arrayTeste['sites'] as $k => $value){
    $newArray[$k] = array(
        'name' => $value,
        'ip'   => $arrayTeste['IPs'][$k],
    );
}

After this function you perform Sort:

function arraySort($array, $on, $order=SORT_ASC){
    $new_array = array();
    $sortable_array = array();

    if (count($array) > 0) {
        foreach ($array as $k => $v) {
            if (is_array($v)) {
                foreach ($v as $k2 => $v2) {
                    if ($k2 == $on) {
                        $sortable_array[$k] = $v2;
                    }
                }
            } else {
                $sortable_array[$k] = $v;
            }
        }

        switch ($order) {
            case SORT_ASC:
                asort($sortable_array);
            break;
            case SORT_DESC:
                arsort($sortable_array);
            break;
        }

        foreach ($sortable_array as $k => $v) {
            $new_array[$k] = $array[$k];
        }
    }

    return $new_array;
}

$newArray = arraySort($newArray, 'name');

Out:

Array
(
    [0] => Array
        (
            [name] => 
            [ip] => 
        )

    [4] => Array
        (
            [name] => 1 Estacao
            [ip] => 172.168.0.11
        )

    [5] => Array
        (
            [name] => 2 Estacao
            [ip] => 172.168.0.12
        )

    [2] => Array
        (
            [name] => 3 Estacao
            [ip] => 172.168.0.13
        )

    [3] => Array
        (
            [name] => 4 Estacao
            [ip] => 172.168.0.14
        )

    [1] => Array
        (
            [name] => 5 Estacao
            [ip] => 172.168.0.15
        )

)
    
30.07.2015 / 20:23
-1

Have you tried using usort ? Order before you create your $data .

function cmpSites($a, $b)
{
    return strcmp($a["sites"], $b["sites"]);
}

function cmpIPs($a, $b)
{
    return strcmp($a["IPs"], $b["IPs"]);
}

usort($lista_estacoes, "cmpSites");
usort($lista_enderecos, "cmpIps");

$data = array( 'sites' => $lista_estacoes, 'IPs' => $lista_enderecos);

IdeOne Example

    
29.06.2015 / 18:40
-1

Try using the array_map() method:


$data = array(
         'sites' => $lista_estacoes,
         'IPs' => $lista_enderecos
         );

          $new_data = array_map($data['sites'], $data['IPs']);

usort($new_data);

print_r($new_data);


    
29.06.2015 / 19:50