PHP - sort arrays of arrays which are values of an assoc array, by element of lowest level array

This is a follow-up to this slightly simpler question. The main difference is the increased complexity of the items being sorted (arrays, not integers), required usort

Sorry about the title, starting to stretch my descriptive powers! I've got a PHP associative array, with strings as keys. Each value is an array of 2-element arrays (they're data points for a graph). I want to sort each array of points, according to the numerical value of the first element in the point. I'm convinced this should be easy, and I've found enough examples that I think I should be doing the right thing, but it's not quite working, so there's a typo or I'm an idiot or something...

PHP:

//Each fruit corresponds to an array (series) of 2-element arrays (data points)
$data = [
    'banana' => [
        [1,1],[3,1],[2,1]
    ],
    'orange' => [
        [5,1],[1,1],[3,1]
    ]
];

echo "Before sort:\n";
var_dump($data);

//For each fruit, I want to order the 2-element arrays by the first element
//NB following previous Q tried & to force reference, doesn't seem to work here
foreach ($data as $key => &$series)
{
    usort($series, 'sortByZeroethElement');
}

echo "\n\nAfter sort:\n";
var_dump($data);

function sortByZeroethElement($a, $b)
{
    return (int) $a[0] > (int) $b[0] ? 1 : (int) $a[0] == (int) $b[0] ? 0 : -1;
}

Output:

Before sort:
array(2) {
  'banana' =>
  array(3) {
    [0] =>
    array(2) {
      [0] =>
      int(1)
      [1] =>
      int(1)
    }
    [1] =>
    array(2) {
      [0] =>
      int(3)
      [1] =>
      int(1)
    }
    [2] =>
    array(2) {
      [0] =>
      int(2)
      [1] =>
      int(1)
    }
  }
  'orange' =>
  array(3) {
    [0] =>
    array(2) {
      [0] =>
      int(5)
      [1] =>
      int(1)
    }
    [1] =>
    array(2) {
      [0] =>
      int(1)
      [1] =>
      int(1)
    }
    [2] =>
    array(2) {
      [0] =>
      int(3)
      [1] =>
      int(1)
    }
  }
}


After sort:
array(2) {
  'banana' =>
  array(3) {
    [0] =>
    array(2) {
      [0] =>
      int(2)
      [1] =>
      int(1)
    }
    [1] =>
    array(2) {
      [0] =>
      int(3)
      [1] =>
      int(1)
    }
    [2] =>
    array(2) {
      [0] =>
      int(1)
      [1] =>
      int(1)
    }
  }
  'orange' =>
  array(3) {
    [0] =>
    array(2) {
      [0] =>
      int(3)
      [1] =>
      int(1)
    }
    [1] =>
    array(2) {
      [0] =>
      int(1)
      [1] =>
      int(1)
    }
    [2] =>
    array(2) {
      [0] =>
      int(5)
      [1] =>
      int(1)
    }
  }
}

Desired result:

'banana' => [
        [1,1],[2,1],[3,1]
    ],
    'orange' => [
        [1,1],[3,1],[5,1]
    ]

As you can see, in the output the inner arrays of points have not been sorted. What am I doing wrong? (PHP 5.5.9, Windows 7)

Answers


your comparison function malfunctions. You need to group the 'else', or it does the following (I believe): in the first else-case it valuates 1 or (int) $a[0] == (int) $b[0]. The next ? then makes it evaluate that as boolean again (1 == true or (int) $a[0] == (int) $b[0]). I added 2 brackets and this works for me:

function sortByZeroethElement($a, $b)
{
    return (int) $a[0] > (int) $b[0] ? 1 : ((int) $a[0] == (int) $b[0] ? 0 : -1);
}

And heres a shorter version using a lambda and some math:

foreach ($data as $key => &$series)
{
    usort($series, function($a, $b) { return $a[0] - $b[0]; });
}

Need Your Help

Catel MVVM Structure

c# wpf mvvm catel

I have a simple WPF Application and I used Catel (3.5) framework for using MVVM.

Close hover div only when clicked outside block

javascript jquery css

I have got a loginbox (blue) that opens when you hover over the text login (Yellow). The box stays open when you go to the loginbox but it closes when you leave it (Mouse in the green area).

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.