0

I want to sort the following array by multiple keys in the following order: First by "type", then "product", and lastly by "name". This is pretty easily done with usort, although my clients wants "product" sorted in a specific order: Stapler, Binder, Book.

$arr = array(
    array(
        'type' => 'School',
        'product' => 'Book',
        'name' => 'My book',
        'data' => '...'
    ),
    array(
        'type' => 'Job',
        'product' => 'Stapler',
        'name' => 'My stapler',
        'data' => '...'
    ),
    array(
        'type' => 'Personal',
        'product' => 'Binder',
        'name' => 'My binder',
        'data' => '...'
    ),
    array(
        'type' => 'School',
        'product' => 'Book',
        'name' => 'My book',
        'data' => '...'
    )
);

Does anyone know a clever way to accomplish this?

1
  • You want something like this <code>array( 'type' => 'School', 'type' => 'Job', 'type' => 'Personal' )</code> Commented Jan 25, 2013 at 9:56

2 Answers 2

1
usort($arr, function ($a, $b) {
  // by type
  $r = strcmp($a['type'], $b['type']);
  if ($r !== 0) {
    return $r;
  }

  // by product
  // note: one might want to check if `$a/$b['product']` really is in `$order`
  $order = array('Stapler', 'Binder', 'Book');
  $r = array_search($a['product'], $order) - array_search($b['product'], $order);
  if ($r !== 0) {
    return $r;
  }

  // or similar, with a little help by @fab ;)
  /*
  $order = array('Stapler' => 0, 'Binder' => 1, 'Book' => 2);
  $r = $order[$a['product']] - $order[$b['product']];
  if ($r !== 0) {
    return $r;
  }
  */

  // name
  return strcmp($a['name'], $b['name']);
});
Sign up to request clarification or add additional context in comments.

Comments

1

usort does not limit you in doing so. I assume your question is how to compare the product value in your sort callback function. This can be done with a map, like:

$mapProductOrder = array_flip(array('Stapler', 'Binder', 'Book'));
// same as: array('Stapler' => 0, 'Binder' => 1, 'Book' => 2)

To compare $item1 and $item2 use:

$mapProductOrder[$item1['product']] < $mapProductOrder[$item2['product']]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.