0

I want to sort a multidimensional array, but I haven't used keys to create it. I used some columns from different tables in my database to store similar data into the array using for loops.

for($x = 0; $x < $numrows; $x++)
{
    $Array[$x][0] = mysql_result($result,$x,"Date");
    $Array[$x][1] = mysql_result($result,$x,"Ref");
    $Array[$x][2] = mysql_result($result,$x,"Amount");
}

First Table is invoice details, the second is Payments made. I'm trying to print out a Statement. All works well, but not in date order. It prints out in the order that I input into the array: All invoice amounts, then all payment amounts. I make the Invoiced amount (-1 * $amount) to filter to Debit or Credit later on as below output.

I print using while loops as the amount of rows will keep growing.

A hard-coded Test Code:

/*#############################
# Sort Multidimentional Array #
#############################*/

  //SET ARRAY

$Array [0][0] = "2016-01-01";
$Array [0][1] = "INV001";
$Array [0][2] = "-500.00";

$Array [1][0] = "2016-02-01";
$Array [1][1] = "INV002";
$Array [1][2] = "-550.00";

$Array [2][0] = "2016-01-05";
$Array [2][1] = "PAY001";
$Array [2][2] = "500.00";

$Array [3][0] = "2016-02-05";
$Array [3][1] = "PAY002";
$Array [3][2] = "500.00";


//SORT ARRAY

/*  Need some help here  */


//PRINT ARRAY
echo "<br/>Print out:<br/><br/>";

for ($x = 0; $x < 4; $x++ )
{
  for ($y = 0; $y < 3; $y++ )
  {
    echo "Array [$x][$y]: ".$Array[$x][$y]."<br/>";
  }
  echo "<br/>";
}

echo "<br/>Done";
?>

I want to sort this in Date order so that after it has been sorted:

$Array [0][0] = "2016-01-01";
$Array [0][1] = "INV001";
$Array [0][2] = "-500.00";

$Array [1][0] = "2016-01-05";
$Array [1][1] = "PAY001";
$Array [1][2] = "500.00";

$Array [2][0] = "2016-02-01";
$Array [2][1] = "INV002";
$Array [2][2] = "-550.00";

$Array [3][0] = "2016-02-05";
$Array [3][1] = "PAY002";
$Array [3][2] = "500.00";

Current output:

+------------+--------+----------+----------+
| DATE       | REF.   | DEBIT    | CREDIT   |
+------------+--------+----------+----------+
| 2016-01-01 | INV001 | R 500.00 |          |
+------------+--------+----------+----------+
| 2016-02-01 | INV002 | R 550.00 |          |
+------------+--------+----------+----------+
| 2016-01-05 | PAY001 |          | R 500.00 |
+------------+--------+----------+----------+
| 2016-02-05 | PAY002 |          | R 500.00 |
+------------+--------+----------+----------+

|                     BALANCE DUE: R  50.00

Wanted output:

+------------+--------+----------+----------+
| DATE       | REF.   | DEBIT    | CREDIT   |
+------------+--------+----------+----------+
| 2016-01-01 | INV001 | R 500.00 |          |
+------------+--------+----------+----------+
| 2016-01-05 | PAY001 |          | R 500.00 |
+------------+--------+----------+----------+
| 2016-02-01 | INV002 | R 550.00 |          |
+------------+--------+----------+----------+
| 2016-02-05 | PAY002 |          | R 500.00 |
+------------+--------+----------+----------+

|                     BALANCE DUE: R  50.00
Ben
  • 1
  • 3
  • 1
    add to query `order by Ref, Date` – splash58 May 09 '16 at 21:15
  • this question and answer will help you i guess: http://stackoverflow.com/questions/96759/how-do-i-sort-a-multidimensional-array-in-php – hakiko May 09 '16 at 21:16
  • 1
    why don't you use mysql `ORDER BY`? – hakiko May 09 '16 at 21:16
  • I'm ordering by Date from the invoice table, and insert them to the Array, then I order by Date in the payments table, and insert into the array. Thank is why unsorted, the output is all invoices first followed by the payments... – Ben May 09 '16 at 21:30

3 Answers3

1

There are many ways to achieve your goal. The best way is, most probably, to get the data already sorted from the database. This way the code is more clear.

Without changing anything in the database queries and the existing data structures, the PHP functions array_column() and array_multisort() can help you reach your goal in two simple steps:

  1. extract the values of Date into a new array called $date (needed by array_multisort() for sorting);
  2. sort the new array $date and $Array simultaneously using array_multisort(). $date is sorted ascending and $Array mimics the changes operated on the keys of $date (that makes its values sorted by Date too).

The code is as simple as:

$date = array_column($Array, 0);             // `Date` is in column 0
array_multisort($date, SORT_ASC, $Array);
// $Array is sorted by column 0 (aka `Date`)
// $date can be unset() now

The PHP function array_column() is available since PHP 5.5. If you are the unlucky user of an older version then there is a simple way to simulate it:

function my_array_column($array, $column)
{
    return array_map(
        function ($item) use ($column) {
            return $item[$column];
        },
        $array
    );
}

This last piece of code uses anonymous functions that were introduced in PHP 5.3. If you are still using PHP 5.3 or an older version then you can use a simple foreach loop to extract the dates better upgrade your PHP.

axiac
  • 56,918
  • 8
  • 77
  • 110
0

Use usort along with a user-defined sort function

<?php

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

  usort($Array, "compare");

?>

the comparison function can be anything that returns an integer value

< 0 for $a less than $b

0 for $a equals $b

> 0 for $a greater than $b

Fred Willmore
  • 3,666
  • 1
  • 21
  • 27
0

It seems like using the old Bubble-sort algorithm might be the only solution...

function bubbleSort(array $Array) 
{
    $array_size = count($Array);
    for($i = 0; $i < $array_size; $i ++) 
    {
        for($j = 0; $j < $array_size; $j ++) 
        {
            if ($Array[$i][0] < $Array[$j][0]) 
            {
                $temp1 = $Array[$i][0];
                $temp2 = $Array[$i][1];
                $temp3 = $Array[$i][2];

                $Array[$i][0] = $Array[$j][0];
                $Array[$i][1] = $Array[$j][1];
                $Array[$i][2] = $Array[$j][2];

                $Array[$j][0] = $temp;
                $Array[$j][1] = $temp;
                $Array[$j][2] = $temp;
            }
        }
    }
    return $Array;
}

$Array = bubbleSort($Array);
Ben
  • 1
  • 3