3

I have an array of objects:

object1->
name="Name1"
key="key1"

object2->
name="Name2"
key="key2"

object3->
name="Name3"
key="key3"

and an array of priority keys:

$keys = ["key3", "key1"];

I need to sort the array of objects based on priority keys, so the result should be:

object3:
name="Name3"
key="key3"

object1->
name="Name1"
key="key1"

object2:
name="Name2"
key="key2"

What is the best way to do it?

1
  • i edited the answer to prioritize only the keys added in the array and leave the rest below them. Commented Dec 11, 2014 at 21:04

3 Answers 3

4

The idea is to add a priority as integer, and sort the array from the highest integer to the lowest using usort()

for example you have this data

 <?php

 $data = [];

 $data[0] = new stdClass;
 $data[0]->name = "name1";
 $data[0]->key = 'key1';

 $data[1] = new stdClass;
 $data[1]->name = "name2";
 $data[1]->key = 'key2';

 $data[2] = new stdClass;
 $data[2]->name = "name3";
 $data[2]->key = 'key3';


 $keys = ["key3", "key1"];

you can sort it this way

function sortByPriority($data , $keys){
    $priority = array();
    $i = count($keys);
    foreach ($keys as $key => $value) {
      $i--;
      $priority[$value] = $i;
    }
    usort($data, function($a, $b) use($priority){
      $a = isset($priority[$a->key]) ? $priority[$a->key] : -1;
      $b = isset($priority[$b->key]) ? $priority[$b->key] : -1;
      return $b - $a;
    });

    return $data;
 }


 var_dump(sortByPriority($data, $keys));    

sample output

array (size=3)
  0 => 
    object(stdClass)[3]
      public 'name' => string 'name3' (length=5)
      public 'key' => string 'key3' (length=4)
  1 => 
    object(stdClass)[1]
      public 'name' => string 'name1' (length=5)
      public 'key' => string 'key1' (length=4)
  2 => 
    object(stdClass)[2]
      public 'name' => string 'name2' (length=5)
      public 'key' => string 'key2' (length=4)    
Sign up to request clarification or add additional context in comments.

Comments

0

Once you prepare your priority lookup array it is merely a matter of passing it into usort()'s scope and either using the related priority value or if the key property's value is not in the priority array, then use the fallback value. Readable, direct, and concise.

Code: (Demo)

$objects = [
   (object)["name" => "Name1", "key" => "key1"],
   (object)["name" => "Name2", "key" => "key2"],
   (object)["name" => "Name3", "key" => "key3"],
];

$keys = ["key3", "key1"];
$lookup = array_flip($keys);
$fallback = count($keys);

usort($objects, function($a, $b) use ($lookup, $fallback) {
    return ($lookup[$a->key] ?? $fallback) <=> ($lookup[$b->key] ?? $fallback);
});

var_export($objects);

Output:

array (
  0 => 
  (object) array(
     'name' => 'Name3',
     'key' => 'key3',
  ),
  1 => 
  (object) array(
     'name' => 'Name1',
     'key' => 'key1',
  ),
  2 => 
  (object) array(
     'name' => 'Name2',
     'key' => 'key2',
  ),
)

From PHP7.4, the syntax can be further condensed and the use() declaration omitted. (Demo)

usort($objects, fn($a, $b) => ($lookup[$a->key] ?? $fallback) <=> ($lookup[$b->key] ?? $fallback));

Comments

-1

There is the function usort in PHP do what you need :

usort( $your_array), "sort_function");
sort_function( $a, $b) {
   // your sort logic
}

3 Comments

how do I involve two arrays in sorting? It is basically sorting of an array depending on values in another array
What is the priority logic in your second array ?
there is no logic, priorities come from another source and I should sort an array based on that

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.