0

Sorry if this is duplicate, I have tried to look at previous posts, but maybe my limited understanding of php gets in the way.

This works to sort arrays 1 and 3 by array 2:

<?php

$ar[1] = array("game","scissors","rock","paper");
$ar[2] = array("D", "B", "A", "C");
$ar[3] =array("four","two","one","three");

array_multisort($ar[2],$ar[1],$ar[3]);

for ($j=0;$j<=3;$j++) {

    for ($i=1;$i<=3;$i++) {
  echo $ar[$i][$j]." ";
}
echo "\n";
}

?>

output:

rock A one
scissors B two
paper C three
game D four

Fine. But I want the list of arrays used as argument for array_multisort() to be specified by user input, so it can't be literal. Instead, I would like the program to decide the order of arrays in the list based on the user input and then name the resulting array of arrays $supar (superarray). But when using $supar as argument for array_multisort(), no sorting is carried out.

<?php

$ar[1] = array("game","scissors","rock","paper");
$ar[2] = array("D", "B", "A", "C");
$ar[3] =array("four","two","one","three");


$supar = array($ar[2],$ar[1],$ar[3]);
array_multisort($supar);

for ($j=0;$j<=3;$j++) {

    for ($i=1;$i<=3;$i++) {
  echo $ar[$i][$j]." ";
}
echo "\n";
}

?>

Output:

game D four
scissors B two
rock A one
paper C three

How should I do to make array_multisort() sort the arrays in $supar by a specified $ar array?

Thank you for your patience.

danbae
  • 563
  • 2
  • 8
  • 22
  • That is not directly possible, that‘s simply not how array_multisort works. If you really need this, you could write your own little wrapper function, that gets your “super array” as parameter, and then calls multisort passing the three sub-arrays as individual parameters. – CBroe Mar 31 '17 at 11:09
  • That would be fine but the ting is, it is not clear beforehand which array is to be first in the list and thus direct the sorting of the others. That will differ depending on input from the user. So how can I create an argument for array_multisort in that case, when I can't make a literal list inside the brackets? Is there another function that would do the trick? My aim is to generate a web page with a list that could be sorted by different parameters chosen by the user – it is very common in web pages... – danbae Mar 31 '17 at 11:19
  • The function you need is [`call_user_func_array('array_multisort', $supar)`](http://php.net/manual/en/function.call-user-func-array.php) – axiac Mar 31 '17 at 11:20
  • Thank you @axiac. But maybe I didn't get how to use this function. Just replacing array_multisort($supar); with call_user_func_array('array_multisort', $supar); gave the same result – no sorting ("game D four" etc). What did I miss? – – danbae Mar 31 '17 at 11:52
  • Oops, you're right. `array_multisort()` gets its parameters passed by reference. – axiac Mar 31 '17 at 11:57
  • I just noticed that you have both `$ar` and `$supar`, having basically the same content. Is there a reason for that? You sort over one but print out the other. – Aioros Mar 31 '17 at 12:01
  • @axiac: is there a way to pass by value instead? – danbae Mar 31 '17 at 12:28
  • @Aioros: Yes I could of course make $ar 2-dimensional. Would that make solving the problem easier? – danbae Mar 31 '17 at 12:30
  • No, I just found strange that you build `$ar` and then put its same element in another array called `$supar`, why not use `$ar` directly? But nevermind, I think @axiac solution is the simplest way. – Aioros Mar 31 '17 at 12:38

2 Answers2

1

You can't do that with just the PHP function. array_multisort() takes the different arrays separately as arguments and you can't just pass a different thing with the intended arguments inside.

What you could do is writing your own function to do that for you. Something like:

function my_multisort($supar) {
    array_multisort($supar[2], $supar[1], $supar[3]);
}

$supar = array(
    array("game","scissors","rock","paper"),
    array("D", "B", "A", "C"),
    array("four","two","one","three")
);

my_multisort($supar);

EDIT

As @axiac correctly pointed out, this is basically a weird specific way of reinventing call_user_func_array(). You can simply build your array of arguments $supar as you need and then do

call_user_func_array('array_multisort', $supar);
Aioros
  • 4,373
  • 1
  • 18
  • 21
1

You can call array_multisort() (or any other function) without specifying its arguments explicitly if you have the arguments in an array by using call_user_func_array().

array_multisort() gets its arguments by reference (in order to be able to modify them). You have to consider this when you build the array you use as argument to call_user_func_array() and put references in this array:

// Input arrays
$ar[1] = array("game", "scissors", "rock", "paper");
$ar[2] = array("D", "B", "A", "C");
$ar[3] = array("four", "two", "one", "three");

// Build the list of arguments for array_multisort()
// Use references to the arrays you want it to sort
$supar = array(&$ar[2], &$ar[1], &$ar[3]);

// Call array_multisort() indirectly
// This is the same as array_multisort($ar[2], $ar[1], $ar[3]);
call_user_func_array('array_multisort', $supar);

Check it in action: https://3v4l.org/ptiog

axiac
  • 68,258
  • 9
  • 99
  • 134
  • Thanks @axiac! That did the trick. Now I can build my superarray piece by piece, which means it can be done by the program when running: `$supar[0]=&$ar[2]; $supar[1]=&$ar[1]; $supar[2]=&$ar[3];` and this gets me the right output. Great! – danbae Mar 31 '17 at 12:37