PHP: re order associative array

后端 未结 7 737
难免孤独
难免孤独 2020-12-10 15:37

In php, I would like to have the ability to re-order an associative array by moving elements to certain positions in the array. Not necessary a sort, just a re-ordering of

相关标签:
7条回答
  • 2020-12-10 15:52

    i made a function based on one answer here. it takes the array of assoc array to be sorted, plus array of keys in which it should be resorted

    // $data = array of assoc array
    // $newKeysOrder = array("c","a","b");
    function resort_assoc_array_by_keys($data, $newKeysOrder) {
      foreach($data as $v) {
        $out = [];
        foreach($newKeysOrder as $k) {
          $out[$k] = $v[$k];
        }  
        $new[] = $out;
      }
      return $new;
    }
    
    0 讨论(0)
  • 2020-12-10 15:54

    I like luky's answer the most but it requires specifying all of the keys. Most of the time you just want order a subset of the keys at the beginning of the array. This function will help then:

    function reorder_assoc_array(
      $cur,   // current assoc array 
      $order  // array conaining ordered (subset of) keys in $cur
    ) {
      $result = [];
      // first copy ordered key/values to result array
      foreach($order as $key) {
        $result[$key] = $cur[$key];
        // unset key in original array
        unset($cur[$key]);
      }
      // ... then copy all remaining keys that were not given in $order
      foreach($cur as $key => $value) {
        $result[$key] = $value;
      }
      return $result;
    }
    

    Example:

    $assoc_arr = [
      'b' => 'bbb',
      'a' => 'aaa',
      'c' => 'ccc',
      'd' => 'ffffd'
    ];
    
    // suppose we want to swap the first two keys and leave the remaining keys as is
    $assoc_arr = reorder_assoc_array($assoc_arr, ['a', 'b']);
    
    // ... the order of keys is now a, b, c, d
    
    0 讨论(0)
  • 2020-12-10 16:02
    $arr = array(
      'a' => 1,
      'b' => 2,
      'move me' => 9,
      'c' => 3,
      'd' => 4,
    );
    

    Hey, I want to move ['move me'] before ['b']. I can do it with only 4 lines of code!

    $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'];
    




    I made a function for easy use:

    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;
    }
    


    Examples:

    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']
    


    I hope this helps a lot of people, because it is an awesome function! :D

    0 讨论(0)
  • 2020-12-10 16:06

    A lot of difficult methods here :) In fact, you can exploit the preserve keys feature of 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);
    
    0 讨论(0)
  • 2020-12-10 16:08

    If you mean to swap two values you could make a function like this:

    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;
        }
    
    0 讨论(0)
  • 2020-12-10 16:12

    array_splice unfortunately doesn't work with associative arrays, so here's something a little messier:

    $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);
    
    0 讨论(0)
提交回复
热议问题