0

Can someone help me about my problem... I have a php multidimensional array and i need to sort it by "PRICE" with PHP... I tried to use sort() but it don't work because every main array have a different currency name..

Here is an example of my array :

array(3) {
  ["MLN"]=>
  array(1) {
    ["EUR"]=>
    array(23) {
      ["FROMSYMBOL"]=>
      string(3) "MLN"
      ["TOSYMBOL"]=>
      string(3) "EUR"
      ["PRICE"]=>
      float(0.01699)
    }
  }
  ["BTC"]=>
  array(1) {
    ["EUR"]=>
    array(23) {
      ["FROMSYMBOL"]=>
      string(3) "BTC"
      ["TOSYMBOL"]=>
      string(3) "EUR"
      ["PRICE"]=>
      int(8769)
    }
  }
  ["LTC"]=>
  array(1) {
    ["EUR"]=>
    array(23) {
      ["FROMSYMBOL"]=>
      string(3) "LTC"
      ["TOSYMBOL"]=>
      string(3) "EUR"
      ["PRICE"]=>
      float(141.47)
    }
  }
}

Is someone who have an idea to sort my currencies by PRICE?

Thanks a lot

1
  • The easiest and most strait forward way is make an new array with prices only and then sort that array with php built in functions. Commented Jan 30, 2018 at 14:03

3 Answers 3

3

You could use uasort():

uasort($array, function($a, $b) {
   return $a['EUR']['PRICE'] - $b['EUR']['PRICE']; 
});

I'm using an anonymous function in this example but you could also define the comparison function separately.

Sign up to request clarification or add additional context in comments.

6 Comments

This. Simple and effective. But shouldnt it be either < or > instead of the minus?
Works and simple, but removes the keys "BTC", "LTC", "MLN".
@ManuelMannhardt the comparison function must return an integer. However, using > would probably work too because the boolean return will be cast to an integer internally.
@Syscall You're right, my fault. I updated my answer from usort() to uasort().
@ManuelMannhardt & Simon it could be <=> which also works for strings arrays and objects, and is like a standard way to compare. It makes it really clear. But in case of numeric comparisons it's just the same of - or <, >.
|
0

You could try something like this :

$sorted = [] ;
foreach ($array as $key => $item) {
    $price = reset($item)['PRICE'] ;
    $sorted[$price] = [$key => $item] ;
}
krsort($sorted);
$array = [];
foreach ($sorted as $sort) {
    $keys = array_keys($sort) ; 
    $array[reset($keys)] = reset($sort) ;
}
unset($sorted);
print_r($array);

Will keep keys and sort array.

Output :

Array
(
    [BTC] => Array
        (
            [EUR] => Array
                (
                    [FROMSYMBOL] => BTC
                    [TOSYMBOL] => EUR
                    [PRICE] => 8769
                )

        )

    [LTC] => Array
        (
            [EUR] => Array
                (
                    [FROMSYMBOL] => LTC
                    [TOSYMBOL] => EUR
                    [PRICE] => 141.47
                )

        )

    [MLN] => Array
        (
            [EUR] => Array
                (
                    [FROMSYMBOL] => MLN
                    [TOSYMBOL] => EUR
                    [PRICE] => 0.01699
                )

        )

)

3 Comments

Thanks a lot for all your fast reply... You have solve my probem !!! :)
While this works, it creates unneeded overhead, since it creates not only one new array, it creates two new arrays, which may cause memory/performance issues if your base array is very huge.
You're right. It create one new array ($sorted). Final $array is overrided.
0

If you want a somewhat messy object oriented approach, I've made a class that is supposed to order an array of classes based on a shared property:

https://gist.github.com/kyrrr/b208693a59f184fe607660e0dfa8631d

A class that represents your data (quick and dirty):

class Exchange{
    public $currencyName;
    public $toSymbol;
    public $rate;
    function __construct($name, $to, $rate)
    {
        $this->currencyName = $name;
        $this->toSymbol = $to;
        $this->rate = $rate;
    }
}

Then you can do:

  $orderer = new PropertyOrderHelper();
  $foo = new Exchange("MLN", "EUR", 0.0169);
  $bar = new Exchange("BTC", "EUR", 20);
  $exchanges = [$foo, $bar];
  var_dump($orderer->orderBy($exchanges, "rate"));
  var_dump($orderer->orderBy($exchanges, "rate", 'desc'));

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.