Use array_multisort() with custom function

2020-04-23 07:21发布

问题:

I have the following array and I would like to sort it according another array and not DESC or ASC

$array = array(
    'note' => array('test', 'test1', 'test2', 'test3', 'test4'),
    'year' => array('2011','2010', '2012', '2009', '2010'),
    'type' => array('journal', 'conference', 'conference', 'conference','conference'),
);

Is it possible to do it with a custom function inside an array_multisort()?

For example:

array_multisort($array['type'], $array['year'], custom_function, $array['note']);

instead of:

array_multisort($array['type'], $array['year'], SORT_ASC, $array['note']);

回答1:

If you know the depth of the array you can simply apply usort on each array element to be sorted.

Here is an example which orders according to a custom array:

<?php
$order = array(
    'first',
    'second',
    'third',
    'fourth',
    'fifth'
);

$array = array(
    array(
        'second',
        'fourth',
        'first',
        'third'
    ),
    array(
        'second',
        'first'
    )
);

foreach($array as &$value) {
    usort($value, function($a, $b) use($order) {
        return array_search($a, $order) > array_search($b, $order);
    });
}
unset($value);

var_dump($array);
/*
array(2) {
  [0]=>
  array(4) {
    [0]=>
    string(5) "first"
    [1]=>
    string(6) "second"
    [2]=>
    string(5) "third"
    [3]=>
    string(6) "fourth"
  }
  [1]=>
  array(2) {
    [0]=>
    string(5) "first"
    [1]=>
    string(6) "second"
  }
}
*/

If you don't know how deep the array can go, the only solution that comes to my mind is a recursive function:

<?php
$order = array(
    'first',
    'second',
    'third',
    'fourth',
    'fifth'
);

$array = array(
    array(
        'second',
        'fourth',
        'first',
        'third'
    ),
    array(
        array('second', 'first'),
        array('fourth', 'third')
    )
);

function custom_multisort($array, $order) {
    foreach($array as &$value) {
        if(is_array($value[0])) {
            $value = custom_multisort($value, $order);
        } else {
            usort($value, function($a, $b) use($order) {
                return array_search($a, $order) > array_search($b, $order);
            });
        }
    }
    return $array;
}

$array = custom_multisort($array, $order);

var_dump($array);
/*
array(2) {
  [0]=>
  array(4) {
    [0]=>
    string(5) "first"
    [1]=>
    string(6) "second"
    [2]=>
    string(5) "third"
    [3]=>
    string(6) "fourth"
  }
  [1]=>
  array(2) {
    [0]=>
    array(2) {
      [0]=>
      string(5) "first"
      [1]=>
      string(6) "second"
    }
    [1]=>
    array(2) {
      [0]=>
      string(5) "third"
      [1]=>
      string(6) "fourth"
    }
  }
}
*/


回答2:

I think its not possible. Instead of that do like this

$custom_function_value = custom_function();
array_multisort($array['type'], $array['year'], $custom_function_value, $array['note']);

I think this will give your desired output.