How to sort json in php

Asked

Viewed 583 times

4

I have the json example I’m using below:


[
  {
    "unidade": "124",
    "bloco": "Bloco B"
  },
  {
    "unidade": "21",
    "bloco": "Bloco A"
  },
  {
    "unidade": "94",
    "bloco": "Bloco A"
  },
  {
    "unidade": "31",
    "bloco": "Bloco B"
  },
  {
    "unidade": "24",
    "bloco": "Bloco B"
  },
  {
    "unidade": "132",
    "bloco": "Bloco A"
  },
  {
    "unidade": "12",
    "bloco": "Bloco A"
  },
  {
    "unidade": "00",
    "bloco": "Bloco B"
  },
  {
    "unidade": "43",
    "bloco": "Bloco B"
  },
  {
    "unidade": "63",
    "bloco": "Bloco A"
  },
  {
    "unidade": "32",
    "bloco": "Bloco B"
  },
  {
    "unidade": "174",
    "bloco": "Bloco B"
  }
]

I need to sort these data so that you prioritize the Block (first the A and then the B) and then order the unit after that. I have already solved the unit, but I cannot solve the block. My code is as below:

<?php

$jsonObj = json_decode($dados);
sort($jsonObj);
foreach ($jsonObj as $buildings){
    echo"$buildings->unidade" "$buildings->bloco";
}

?>

5 answers

4


Lucas, follow code. I’ve commented the code to you.

<?php

//Criando Array
$resultados ='[
  {
    "unidade": "124",
    "bloco": "Bloco B"
  },
  {
    "unidade": "21",
    "bloco": "Bloco A"
  },
  {
    "unidade": "94",
    "bloco": "Bloco A"
  },
  {
    "unidade": "31",
    "bloco": "Bloco B"
  },
  {
    "unidade": "24",
    "bloco": "Bloco B"
  },
  {
    "unidade": "132",
    "bloco": "Bloco A"
  },
  {
    "unidade": "12",
    "bloco": "Bloco A"
  },
  {
    "unidade": "00",
    "bloco": "Bloco B"
  },
  {
    "unidade": "43",
    "bloco": "Bloco B"
  },
  {
    "unidade": "63",
    "bloco": "Bloco A"
  },
  {
    "unidade": "32",
    "bloco": "Bloco B"
  },
  {
    "unidade": "174",
    "bloco": "Bloco B"
  }
]';
    $arr = json_decode($resultados, true);


    $sort = array();
    foreach($arr as $k => $v) {
        $sort['unidade'][$k] = $v['unidade'];
        $sort['bloco'][$k] = $v['bloco'];
    }

    //aqui é realizado a ordenação do array
    array_multisort($sort['bloco'], SORT_ASC, $sort['unidade'], SORT_ASC,$arr);

    //abaixo é listado o resultado ordenado  
    foreach($arr as $k => $v) {
        echo 'Unidade: ' . $sort['unidade'][$k] = $v['unidade'] . ' - ';
        echo $sort['bloco'][$k] = $v['bloco'] . '<br>';
    }
?>

2

Here’s an example of how to do this:

<?php
$resultados ='[
  {
    "unidade": "124",
    "bloco": "Bloco B"
  },
  {
    "unidade": "21",
    "bloco": "Bloco A"
  },
  {
    "unidade": "94",
    "bloco": "Bloco A"
  },
  {
    "unidade": "31",
    "bloco": "Bloco B"
  },
  {
    "unidade": "24",
    "bloco": "Bloco B"
  },
  {
    "unidade": "132",
    "bloco": "Bloco A"
  },
  {
    "unidade": "12",
    "bloco": "Bloco A"
  },
  {
    "unidade": "00",
    "bloco": "Bloco B"
  },
  {
    "unidade": "43",
    "bloco": "Bloco B"
  },
  {
    "unidade": "63",
    "bloco": "Bloco A"
  },
  {
    "unidade": "32",
    "bloco": "Bloco B"
  },
  {
    "unidade": "174",
    "bloco": "Bloco B"
  }
]';
$arr = json_decode($resultados, true);
$sort = array();
foreach($arr as $k=>$v) {
$sort['unidade'][$k] = $v['unidade'];
$sort['bloco'][$k] = $v['bloco'];
}
array_multisort($sort['bloco'], SORT_ASC, $sort['unidade'], SORT_ASC,$arr);
print_r($arr);


?>

  • The logic worked, but I’m still struggling with Print_r(). Needed the output of the program to look like this: 11 Block A 12 Block A 13 Block A Know how I can do this?

  • @lucasmenezes vc want to order first the block and then the units, this?

  • @Leandroalfredo That’s right Leandro, the Block has priority at the time of making the ordering. But I need it to exit without that full output of information about the array equal to this: Array ( [0] => Array ( [unit] => 11 [block] => Block A ) [1] => Array ( [unit] => 12 [block] => Block A ) [2] *As I’m still a beginner in PHP I don’t know much about handling these outputs.

  • ah yes, I will post new answer for you

2

Can be done using usort to sort, just implement the ordering comparison yourself, in the logic I used was to return the block with smaller unit when comparing two elements of the same block, otherwise compared the block name.

$json = '[ { "unidade": "124", "bloco": "Bloco B" }, { "unidade": "21", "bloco": "Bloco A" }, { "unidade": "94", "bloco": "Bloco A" }, { "unidade": "31", "bloco": "Bloco B" }, { "unidade": "24", "bloco": "Bloco B" }, { "unidade": "132", "bloco": "Bloco A" }, { "unidade": "12", "bloco": "Bloco A" }, { "unidade": "00", "bloco": "Bloco B" }, { "unidade": "43", "bloco": "Bloco B" }, { "unidade": "63", "bloco": "Bloco A" }, { "unidade": "32", "bloco": "Bloco B" }, { "unidade": "174", "bloco": "Bloco B" } ]';
$json = json_decode($json, true);

usort($json, function($x, $y) { 
    if ($x['bloco'] === $y['bloco']) {
        return $x['unidade'] > $y['unidade']  ? +1 : -1;
    } else {
        return $x['bloco'] > $y['bloco']  ? +1 : -1;
    }
});

var_dump($json);

2

The function usort gives a lot of control over sorting. This function will sort an array by values using a user-defined sorting function.

If the array needs to be ordered using a peculiar criterion, you should use this function.

The comparison is done in two elements ($a and $b) and follows the following table of returns:

  • -1 : if $a < $b
  • 0 : if $a == $b
  • 1 : if $a > $b

Answer:

<?php
$resultados ='[
  {
    "unidade": "124",
    "bloco": "Bloco B"
  },
  {
    "unidade": "21",
    "bloco": "Bloco A"
  },
  {
    "unidade": "94",
    "bloco": "bLoCo a"  //<--- Não falha, o algorítimo é insensível a capitalização
  },
  {
    "unidade": "31",
    "bloco": "Bloco B"
  },
  {
    "unidade": "24",
    "bloco": "Bloco B"
  },
  {
    "unidade": "132",
    "bloco": "Bloco A"
  },
  {
    "unidade": "12",
    "bloco": "Bloco C"
  },
  {
    "unidade": "00",
    "bloco": "Bloco B"
  },
  {
    "unidade": "43",
    "bloco": "Bloco C"
  },
  {
    "unidade": "63",
    "bloco": "Bloco A"
  },
  {
    "unidade": "32",
    "bloco": "Bloco B"
  },
  {
    "unidade": "174",
    "bloco": "Bloco B"
  }
]';


$arr = json_decode($resultados, false);

usort($arr, function($a, $b) {   
    // Primeiro compara os blocos
    $cmp2 = strcasecmp($a->bloco , $b->bloco);
      if ($cmp2 === 0) { // Se os blocos forem iguais compara as unidades
        if ($a->unidade < $b->unidade) {
          return -1;
      } elseif ($a->unidade > $b->unidade) {
          return 1;
      } else return 0;
    } else return $cmp2; //Se os blocos forem diferentes retorna a comparação entre si.  
});

// Imprime os resultados
echo PHP_EOL;
foreach($arr as $u) {
    echo 'Unidade: ' . $u->unidade . ' - ';
    echo $u->bloco  . PHP_EOL;
}


?>

1

If it’s Laravel let’s do it the Laravel way, using Collection you can do something like below.

 $a = '[
  {
    "unidade": "124",
    "bloco": "Bloco B"
  },
  {
    "unidade": "21",
    "bloco": "Bloco A"
  },
  {
    "unidade": "94",
    "bloco": "Bloco A"
  }
]';

 $b = json_decode($a);


 $collection = collect($b);
 $sorted = $collection->sortBy('bloco');
 print_r($sorted->values()->all());//dump|dd|var_dump ...

I did not have to test because I am without the Laravel in my machine. I recommend to see the doc https://laravel.com/docs/5.8/collections https://laravel.com/docs/5.8/helpers#method-Collect

Browser other questions tagged

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