Split array and sort

Asked

Viewed 744 times

3

I have an array as follows:

'Ato001_1981',
'Ato002_1980',
'Ato003_1982',
'Ato003_1983',
'Ato004_1982',
'Ato013_1981',
'Ato013_1982',
'Ato013_1988',
'Ato031_1982',
'Ato032_1979',
'Ato039_1988',
'Ato060_1987',
'Ato065_1988',
'Ato066_1988',
'Ato067_1988',
'Ato076_1987',
'Ato077_1988',
'Ato078_1988',
'Ato095_1987',
'Ato137_1987',
'Ato144_1987'

I would like to break each row of the array to take the name and the year and then sort as in the text below:

Ano     Tipo
1988    Ato078
1988    Ato077
1988    Ato067
1988    Ato066
1988    Ato065
1988    Ato039
1988    Ato013
1987    Ato144
1987    Ato137
1987    Ato095
1987    Ato076
1987    Ato060
1983    Ato003
1982    Ato031
1982    Ato013
1982    Ato004
1982    Ato003
1981    Ato013
1981    Ato001
1980    Ato002
1979    Ato032

I tried the code below, but without success:

$new = array();
foreach($texto as $item):
    $valor = explode('_', $item);
    $new['ano'] = $valor[1];
    $new['tipo'] = $valor[0];    
    print_r($new);    
endforeach;
  • The problem is how to sort based on ano and from the largest to the smallest?

3 answers

2

$texto = array(
    'Ato001_1981',
    'Ato002_1980',
    'Ato003_1982',
    'Ato003_1983',
    'Ato004_1982',
    'Ato013_1981',
    'Ato013_1982',
    'Ato013_1988',
    'Ato031_1982',
    'Ato032_1979',
    'Ato039_1988',
    'Ato060_1987',
    'Ato065_1988',
    'Ato066_1988',
    'Ato067_1988',
    'Ato076_1987',
    'Ato077_1988',
    'Ato078_1988',
    'Ato095_1987',
    'Ato137_1987',
    'Ato144_1987'
);

$new = array();
foreach($texto as $item):
    $valor = explode('_', $item);
    $new = ['ano' => $valor[1], 'tipo' => $valor[0]];

    echo $new['ano'] . '  ' . $new['tipo'] . '<br />';
endforeach;

Here it worked like this.

  • 1

    I didn’t understand how you ordered the array.

  • Thank you, it worked perfectly

  • OOG @rray (Gambiarra oriented orientation)

2


In the most elegant way possible, let’s go to the solution:

Your array is as follows:

$dados = array(
    'Ato001_1981',
    'Ato002_1980',
    'Ato003_1982',
    'Ato003_1983',
    'Ato004_1982',
    'Ato013_1981',
    'Ato013_1982',
    'Ato013_1988',
    'Ato031_1982',
    'Ato032_1979',
    'Ato039_1988',
    'Ato060_1987',
    'Ato065_1988',
    'Ato066_1988',
    'Ato067_1988',
    'Ato076_1987',
    'Ato077_1988',
    'Ato078_1988',
    'Ato095_1987',
    'Ato137_1987',
    'Ato144_1987'
);

First let’s turn this array. I believe that the most appropriate function for this is using array_map, for variable scope protection and own functionality for generating arrays based on other.

$array = array_map(function ($value){
    return explode('_', $value);
}, $dados);

Later we will use usort, comparing the values of array, through a callback in order to order it.

usort($array, function ($v1, $v2)
{
    $diff = $v2[1] - $v1[1];

    if ($diff) return $diff;

    return strcmp($v2[0], $v1[0]);

});

And finally, we have the array - obtained with var_export.

array (
  0 => 
  array (
    0 => 'Ato078',
    1 => '1988',
  ),
  1 => 
  array (
    0 => 'Ato077',
    1 => '1988',
  ),
  2 => 
  array (
    0 => 'Ato067',
    1 => '1988',
  ),
  3 => 
  array (
    0 => 'Ato066',
    1 => '1988',
  ),
  4 => 
  array (
    0 => 'Ato065',
    1 => '1988',
  ),
  5 => 
  array (
    0 => 'Ato039',
    1 => '1988',
  ),
  6 => 
  array (
    0 => 'Ato013',
    1 => '1988',
  ),
  7 => 
  array (
    0 => 'Ato144',
    1 => '1987',
  ),
  8 => 
  array (
    0 => 'Ato137',
    1 => '1987',
  ),
  9 => 
  array (
    0 => 'Ato095',
    1 => '1987',
  ),
  10 => 
  array (
    0 => 'Ato076',
    1 => '1987',
  ),
  11 => 
  array (
    0 => 'Ato060',
    1 => '1987',
  ),
  12 => 
  array (
    0 => 'Ato003',
    1 => '1983',
  ),
  13 => 
  array (
    0 => 'Ato031',
    1 => '1982',
  ),
  14 => 
  array (
    0 => 'Ato013',
    1 => '1982',
  ),
  15 => 
  array (
    0 => 'Ato004',
    1 => '1982',
  ),
  16 => 
  array (
    0 => 'Ato003',
    1 => '1982',
  ),
  17 => 
  array (
    0 => 'Ato013',
    1 => '1981',
  ),
  18 => 
  array (
    0 => 'Ato001',
    1 => '1981',
  ),
  19 => 
  array (
    0 => 'Ato002',
    1 => '1980',
  ),
  20 => 
  array (
    0 => 'Ato032',
    1 => '1979',
  ),
)
  • 2

    Thank you. it worked out the way I was needing it

1

The least bad way to sort the key-based array is to use usort()

function cmp($a, $b) {
    return $a["ano"] < $b["ano"];
}


$texto = ['Ato001_1981','Ato002_1980','Ato003_1982','Ato003_1983','Ato004_1982','Ato013_1981'];

$new = array();
$index  = 0;
foreach($texto as $item){
    $valor = explode('_', $item);
    $new[$index]['tipo'] = $valor[0];
    $new[$index]['ano'] = $valor[1];
    $index++;
}

usort($new, "cmp");

echo '<pre>';
print_r($new);

Refrencia: Soen - Sort php multidimensional array by sub-value

  • I got the similar result but in your case is happening the same thing as mine, the array is grouping equal items, how can we make it so that it does not group?

  • @Rafaelacioly, grouping? used $index to define keys that do not repeat themselves, if you base only on the year ai it overwrites the key every time.

  • The result that I had with its group method here, only appeared 5 arrays. the result here; http://pastebin.com/dyHu3Jc3

  • Here are 20 elements, in the example of the answer I only put 5 elements. @Rafaelacioly. The error was that the order was asc and should be desc that I got right.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.