David Gard
David Gard

Reputation: 12047

Move an associative array key within an array

How can I move an associate key in an array so that it is after another specified key?

For example, the current output of $columns is as follows -

$columns = Array(
    [title] => Title
    [author] => Author
    [taxonomy-news_type] => News Types
    [date] => Date
    [wpseo-score] => SEO
    [p2p-from-news_to_people] => Staff linked to this Story
    [show_item_ids] => ID
)

One scenario is that I would like to move the key p2p-from-news_to_people to directly after taxonomy-news_type, producing this output -

$columns = Array(
    [title] => Title
    [author] => Author
    [taxonomy-news_type] => News Types
    [p2p-from-news_to_people] => Staff linked to this Story
    [date] => Date
    [wpseo-score] => SEO
    [show_item_ids] => ID
)

Upvotes: 1

Views: 1238

Answers (6)

Michael
Michael

Reputation: 12806

This should do what you need:

// The columns
$columns = array(

  'title'                   => 'Title',
  'author'                  => 'Author',
  'taxonomy-news_type'      => 'News Types',
  'date'                    => 'Date',
  'wpseo-score'             => 'SEO',
  'p2p-from-news_to_people' => 'Staff linked to this Story',
  'show_item_ids'           => 'ID',

);

/**
 * Move array element before another
 *
 * @param array $array
 * @param string $move
 * @param string $before
 * @return array
 */
function array_move_before(array $array, $move, $before)
{

  // Get the element to move
  $move = array_splice(

    $array,
    array_search($move, array_keys($array)),
    1

  );

  // Get the element to move before
  $offset = array_search($before, array_keys($array));

  // Return the new array
  return array_merge(

    array_slice($array, 0, $offset),
    $move,
    array_slice($array, $offset, NULL)

  );

}

// Get the new array
$result = array_move_before($columns, 'p2p-from-news_to_people', 'date');

// Output the array
print_r($result);

This gives:

Array
(
    [title] => Title
    [author] => Author
    [taxonomy-news_type] => News Types
    [p2p-from-news_to_people] => Staff linked to this Story
    [date] => Date
    [wpseo-score] => SEO
    [show_item_ids] => ID
)

Upvotes: 1

Amal Murali
Amal Murali

Reputation: 76656

You can build a custom function to insert a new item after a specific key:

function array_insert_after($array, $findAfter, $key, $new)
{
    $pos = (int) array_search($findAfter, array_keys($array)) + 1;
    return array_merge(
        array_slice($array, 0, $pos),
        array($key => $new),
        array_slice($array, $pos)
    );
}

Usage:

$elem = $arr['p2p-from-news_to_people'];  // store the value
unset($arr['p2p-from-news_to_people']);   // unset the var

$arr = array_insert_after(
    $arr,                      /* original array */
    'taxonomy-news_type',      /* item after which the elem should be inserted */
    'p2p-from-news_to_people', /* key of the elem */
    $elem                      /* the value of the elem */
);

print_r($arr);

Output:

Array
(
    [title] => Title
    [author] => Author
    [taxonomy-news_type] => News Types
    [p2p-from-news_to_people] => Staff linked to this Story
    [date] => Date
    [wpseo-score] => SEO
    [show_item_ids] => ID
)

Demo

Upvotes: 4

ex3v
ex3v

Reputation: 3566

In general:

  1. Split your current array into two parts ($larray, $rarray)- before and after place you want to insert your key (for example using foreach).

  2. Add your new key to the end of left side, for example $larray = $larray + array('key' => 'value')

  3. Add right side to that: `$array = $larray + $rarray'

It's good to sometimes not copy-paste solutions for web, but to just understand them. It's fun!

Upvotes: -1

jasir
jasir

Reputation: 1471

Snippet from Nette framework (second method)

   /**
    * Searches the array for a given key and returns the offset if successful.
    * @return int    offset if it is found, FALSE otherwise
    */
   public static function searchKey($arr, $key)
   {
      $foo = array($key => NULL);
      return array_search(key($foo), array_keys($arr), TRUE);
   }


   /**
    * Inserts new array before item specified by key.
    * @return void
    */
   public static function insertBefore(array & $arr, $key, array $inserted)
   {
      $offset = self::searchKey($arr, $key);
      $arr = array_slice($arr, 0, $offset, TRUE) + $inserted + array_slice($arr, $offset, count($arr), TRUE);
   }

Upvotes: 1

Mario Radomanana
Mario Radomanana

Reputation: 1698

To put an element before or after one element, I use these two functions

/**
 * @return array
 * @param array $src
 * @param array $in
 * @param int|string $pos
*/
function array_push_before($src,$in,$pos){
    if(is_int($pos)) $R=array_merge(array_slice($src,0,$pos), $in, array_slice($src,$pos));
    else{
        foreach($src as $k=>$v){
            if($k==$pos)$R=array_merge($R,$in);
            $R[$k]=$v;
        }
    }return $R;
}

/**
 * @return array
 * @param array $src
 * @param array $in
 * @param int|string $pos
*/
function array_push_after($src,$in,$pos){
    if(is_int($pos)) $R=array_merge(array_slice($src,0,$pos+1), $in, array_slice($src,$pos+1));
    else{
        foreach($src as $k=>$v){
            $R[$k]=$v;
            if($k==$pos)$R=array_merge($R,$in);
        }
    }return $R;
}

Maybe you can put the content of [p2p-from-news_to_people] in a variable and delete it after. Then use one of the functions above to reposition it.

$foo = array('p2p-from-news_to_people' => $columns['p2p-from-news_to_people']);
unset($columns['p2p-from-news_to_people']);
array_push_after($columns, $foo, 'taxonomy-news_type');

EDIT :

There are other solutions at this link for a similar problem Change index order in array

Upvotes: 1

Dysosmus
Dysosmus

Reputation: 832

You can do that with array_splice look here or use a custom sort function.

Upvotes: -1

Related Questions