2012-06-13 7 views
3

Я хотел бы отсортировать следующий массив, используя другой массив, приведенный ниже.Сортировка массива с использованием другого массива в качестве ввода

Например. У меня есть следующий массив:

[note] => Array 
(
    [0] => 'note1' 
    [1] => 'note2' 
    [2] => 'note3' 
), 
[text] => Array 
(
    [0] => 'text1' 
    [2] => 'test3' 
), 
[year] => Array 
(
    [0] => '2002' 
    [1] => '2000' 
    [2] => '2011' 
) 

И у меня есть массив:

$sortBy = array('2011', '2000', '2002'). 

Я хотел бы отсортировать выше массив по значению $ SortBy массива.

Желаемый результат:

[note] => Array 
(
    [0] => 'note3' 
    [1] => 'note2' 
    [2] => 'note1' 
), 
[text] => Array 
(
    [0] => 'test3' 
    [2] => 'text1' 
), 
[year] => Array 
( 
    [0] => '2011' 
    [1] => '2000' 
    [2] => '2002' 
) 
+0

Здесь я чувствую себя немного мусором. – hakre

+0

@hakre, ты уверен? Я не думаю, что это подходит. – goat

+0

@rambocoder: Посмотрите здесь: http://stackoverflow.com/a/11022569/367456 - это многопользовательский режим (и вы можете дополнительно использовать сопоставление 'array_flip', которое вы используете). – hakre

ответ

3

У вас есть массив:

$array = array(
    'note' => array('note1', 'note2', 'note3'), 
    'text' => array('text1', 'text2', 'text3'), 
    'year' => array('2002', '2000', '2011') 
); 

И порядок чего-то:

$sortBy = array('2011', '2000', '2002'); 
$sortOrder = $array['year']; 

Затем выяснить, как год должен быть отсортирован:

array_walk($sortOrder, function(&$v) use ($sortBy) {$v = array_search($v, $sortBy);}); 

Чтобы затем отсортировать весь массив, основанный на таком порядке:

array_multisort($sortOrder, $array['note'], $array['text'], $array['year']); 

Полный текст:

$array = array(
    'note' => array('note1', 'note2', 'note3'), 
    'text' => array('text1', 'text2', 'text3'), 
    'year' => array('2002', '2000', '2011') 
); 
$sortBy = array('2011', '2000', '2002'); 
$sortOrder = $array['year']; 
array_walk($sortOrder, function(&$v) use ($sortBy) {$v = array_search($v, $sortBy);}); 
array_multisort($sortOrder, $array['note'], $array['text'], $array['year']); 

Выход/Demo:

Array(
    [note] => Array(
      [0] => note3 
      [1] => note2 
      [2] => note1 
     ) 
    [text] => Array(
      [0] => text3 
      [1] => text2 
      [2] => text1 
     ) 
    [year] => Array(
      [0] => 2011 
      [1] => 2000 
      [2] => 2002 
     ) 
) 

Edit: Подключенный вариант, бережет array_search:

$sortBy = array_flip(array('2011', '2000', '2002')); 
$sortOrder = $array['year']; 
array_walk($sortOrder, function(&$v) use ($sortBy) {$v = $sortBy[$v];}); 
array_multisort($sortOrder, $array['note'], $array['text'], $array['year']); 

edit2: PHP 5.2, завернутые в одну функцию, полная параметризация:

/** 
* @param array $array 
* @param string|int $by key/offset 
* @param array $order 
* @return array 
*/ 
function array_multisort_by_order(array $array, $by, array $order) 
{ 
    $order = array_flip($order); 
    $params[] = $array[$by]; 
    foreach($params[0] as &$v) $v = $order[$v]; 
    foreach($array as &$v) $params[] = &$v; unset($v); 
    call_user_func_array('array_multisort', $params); 
    return $array; 
} 

// Usage: 
array_multisort_by_order($array, 'year', array('2011', '2000', '2002')); 
+0

Я получаю Предупреждение: array_multisort(): размеры массива несовместимы. – glarkou

+0

Для чего из многих примеров? И возьмите случайный массив как все одинаковое количество значений для каждого подматрица. – hakre

+0

Я использовал функцию, которую вы предоставили в конце, и каждый поддиапазон * не имеет * одинакового количества значений. – glarkou

0

Я именовании массив будет отсортирован в $ стоге сена.

$newArray = array(); // not necessary, but starts your new array 
// you know how you want to sort it, so loop through your sorting array 
foreach($sortBy as $year){ 
    // get the key of the 2nd level of the 2D array, which we are saving as $k 
    foreach($haystack['year'] as $key => $value){ 
     if($value == $year) $k = $key; 
     break; // since we got what we need, we don't need to let this foreach loop finish 
     // you could also do an array_search() here instead of this foreach 
    } 
    if($k > 0){ 
     // if k is 0, we didn't find that value so we're not going to sort it or include it in the new array 
     foreach($haystack as $key => $a){ 
     // just save it into a new array 
     $newArray[$key][$k] = $a;  
     } 
    } 
} 
var_dump($newArray); 
2

Я хотел бы сделать функцию для него, как это:

function sort_by($arr, $sub, $order){ 
    // Create a map from old key to new key 
    $value_kmap = array_flip($arr[$sub]); 
    $sort_kmap = array_flip($order); 
    foreach($order as $value) 
     $kmap[$value_kmap[$value]] = $sort_kmap[$value]; 

    // Create your result array 
    foreach($arr as $name => $sub_arr) 
     foreach($kmap as $key => $new_key) 
      if(isset($sub_arr[$key])) 
       $result[$name][$new_key] = $sub_arr[$key]; 

    return $result; 
} 

Функция не является родовым делает никаких ссылок на year. Требуется имя вспомогательного массива для сортировки в качестве аргумента. Вы бы использовать его как это:

$arr = array(
    'note' => array('note1', 'note2', 'note3'), 
    'text' => array('text1', 'text3'), 
    'year' => array('2002', '2000', '2011') 
); 

print_r(sort_by($arr, 'year', array('2011', '2000', '2002'))); 

выходы [Codepad]:

 
Array 
(
    [note] => Array 
     (
      [0] => note3 
      [1] => note2 
      [2] => note1 
     ) 

    [text] => Array 
     (
      [1] => text3 
      [2] => text1 
     ) 

    [year] => Array 
     (
      [0] => 2011 
      [1] => 2000 
      [2] => 2002 
     ) 

) 
+0

Спасибо большое. Это восхитительно! – glarkou

+0

@salamis Нет проблем! :) – Paulpro

+0

технически это не делает то, что было задано, потому что вы переиндексировали цифровые клавиши. в действительности, это, вероятно, желательно. – goat

0

непроверенный (вы должны предоставить var_export() ваш массив, когда вы размещаете эти любопытные вопросы)

//$orig = ... 

$sorted = array(); 

$map = array_flip($orig['year']); 
foreach ($sortBy as $year) { 
    $originalNumerickey = $map[$year]; 
    foreach ($orig as $stringKey => $subArray) { 
     $sorted[$stringKey][$originalNumerickey] = $subArray[$originalNumerickey]; 
    } 
} 
Смежные вопросы