2012-07-01 16 views
6

W php chciałbym mieć możliwość ponownego uporządkowania tablicy asocjacyjnej poprzez przeniesienie elementów do określonych pozycji w tablicy. Nie trzeba tego sortować, po prostu zamawiam mój wybór.PHP: uporządkuj tablicę asocjacyjną

Jako przykład załóżmy, że mam asocjacyjnej następująco:

array(
'a' => 'Element A', 
'b' => 'Element B', 
'c' => 'Element C', 
); 

a w jednym przypadku, i może chcieć, aby przesunąć C przed B i mają następujący wynik:

array(
'a' => 'Element A', 
'c' => 'Element C', 
'b' => 'Element B', 
); 

lub w innym przypadku mogę chcieć przenieść C przed A i uzyskać następujący wynik:

array(
'c' => 'Element C', 
'a' => 'Element A', 
'b' => 'Element B', 
); 

Co próbuję pokazać , jest po prostu metodą powiedzenia "Hej, chcę przesunąć ten element tablicy przed tym innym elementem tablicy" lub "Hej, id lubię przesuwać ten element tablicy, aby upewnić się, że przychodzi po tym innym elemencie tablicowym"

Mam nadzieję, że to ma sens!

Dziękuję każdemu z góry, kto dba, aby mi pomóc z tym

+1

Tablica asocjacyjna nie ma żadnego zamówienia. – DonCallisto

+13

@DonCallisto: To całkowicie nieprawda. Tablice są także listami i jako takie zdecydowanie mają ściśle określoną kolejność. – Jon

+0

możliwy duplikat [Sortuj tablicę używając innej tablicy] (http://stackoverflow.com/questions/8935093/sort-array-using-another-array) – nickb

Odpowiedz

2

Jeśli masz na myśli, aby zamienić dwie wartości można dokonać funkcję tak:

function array_swap($key1, $key2, $array) { 
     $newArray = array(); 
     foreach ($array as $key => $value) { 
      if ($key == $key1) { 
       $newArray[$key2] = $array[$key2]; 
      } elseif ($key == $key2) { 
       $newArray[$key1] = $array[$key1]; 
      } else { 
       $newArray[$key] = $value; 
      } 
     } 
     return $newArray; 
    } 
+1

Dziękuję za odpowiedź, ale muszę również przenieść klucze, a nie tylko wartości –

+0

Teraz wypróbuj nową funkcję –

8

Dla niestandardowych sortowania, można na przykład utworzyć tablicę, która jest pożądana kolejność kluczy, a następnie skojarzyć wartości z nimi. Przykład:

$input = array("a"=>"Element A","b"=>"Element B","c"=>"Element C"); 
$order = array("c","a","b"); 
$out = array(); 
foreach($order as $k) { 
    $out[$k] = $input[$k]; 
} 

elementy w $out znajdzie się w określonej kolejności.

+0

Nie działałoby to na mój problem. Muszę przenieść jeden element przed lub po innym elemencie. Tak więc moja metoda otrzyma tylko dwa klucze –

0

array_splice niestety nie działa z asocjacyjnych, więc o coś trochę bałaganu:

$keys = array_keys($arr); 
$values = array_values($arr); 

$keyIndex = array_search($someKey, $keys); 
array_splice($keys, $keyIndex, 1); 
array_splice($values, $keyIndex, 1); 

$insertIndex = 1; 
array_splice($keys, $insertIndex, 0, array($someKey)); 
array_splice($values, $insertIndex, 0, array($arr[$someKey])); 

$arr = array_combine($keys, $values); 
7
$arr = array(
    'a' => 1, 
    'b' => 2, 
    'move me' => 9, 
    'c' => 3, 
    'd' => 4, 
); 

Hej, chcę przenieść ["przenieś mnie"] przed ["b"]. Mogę to zrobić tylko z 4 liniami kodu!

$i = 0; foreach($arr as &$val) $val = array('sort' => (++$i * 10), 'val' => $val); 
$arr['move me']['sort'] = $arr['b']['sort'] - 5; 
uasort($arr, function($a, $b) { return $a['sort'] > $b['sort']; }); 
foreach($arr as &$val) $val = $val['val']; 




Zrobiłem funkcję dla łatwego użycia:

function move_item(&$ref_arr, $key1, $move, $key2 = null) 
{ 
    $arr = $ref_arr; 
    if($key2 == null) $key2 = $key1; 
    if(!isset($arr[$key1]) || !isset($arr[$key2])) return false; 

    $i = 0; foreach($arr as &$val) $val = array('sort' => (++$i * 10), 'val' => $val); 

    if(is_numeric($move)) 
    { 
    if($move == 0 && $key1 == $key2) return true; 
    elseif($move == 0) { $tmp = $arr[$key1]['sort']; $arr[$key1]['sort'] = $arr[$key2]['sort']; $arr[$key2]['sort'] = $tmp; } 
    else $arr[$key1]['sort'] = $arr[$key2]['sort'] + ($move * 10 + ($key1 == $key2 ? ($move < 0 ? -5 : 5) : 0)); 
    } 
    else 
    { 
    switch($move) 
    { 
     case 'up':  $arr[$key1]['sort'] = $arr[$key2]['sort'] - ($key1 == $key2 ? 15 : 5); break; 
     case 'down': $arr[$key1]['sort'] = $arr[$key2]['sort'] + ($key1 == $key2 ? 15 : 5); break; 
     case 'top': $arr[$key1]['sort'] = 5; break; 
     case 'bottom': $arr[$key1]['sort'] = $i * 10 + 5; break; 
     default: return false; 
    } 
    } 
    uasort($arr, function($a, $b) { return $a['sort'] > $b['sort']; }); 
    foreach($arr as &$val) $val = $val['val']; 
    $ref_arr = $arr; 
    return true; 
} 


Przykłady:

move_item($arr, 'move me', 'up'); //move it one up 
move_item($arr, 'move me', 'down'); //move it one down 
move_item($arr, 'move me', 'top'); //move it to top 
move_item($arr, 'move me', 'bottom'); //move it to bottom 

move_item($arr, 'move me', -1); //move it one up 
move_item($arr, 'move me', 1); //move it one down 
move_item($arr, 'move me', 2); //move it two down 

move_item($arr, 'move me', 'up', 'b'); //move it before ['b'] 
move_item($arr, 'move me', -1, 'b'); //move it before ['b'] 
move_item($arr, 'move me', 'down', 'b'); //move it after ['b'] 
move_item($arr, 'move me', 1, 'b'); //move it after ['b'] 
move_item($arr, 'move me', 2, 'b'); //move it two positions after ['b'] 

//Special syntax, to swap two elements: 
move_item($arr, 'a', 0, 'd'); //Swap ['a'] with ['d'] 


Mam nadzieję, że to pomaga wiele osób, gdyż jest niesamowitym functi na! : D

1

Wiele trudnych metod tutaj :) W rzeczywistości można wykorzystać funkcję preserve keys z array_slice().

$new_element = array('new_key' => 'value'); 

// if needed, find the insertion index by key 
$index = array_search('key to search', array_keys($old_array)); 

// add element at index (note the last array_slice argument) 
$new_array = array_slice($old_array, 0, $index+1, true) + $new_element + array_slice($old_array, $index+1, null, true); 
Powiązane problemy