1

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
)
5
  • Why? It doesn't seem like these values need to be ordinal. Commented Jan 24, 2014 at 15:04
  • They are columns for a table and I wish to change the order in which they are output. Thanks. Commented Jan 24, 2014 at 15:05
  • @DavidGard why not change the order in the table then? Or change the order they are loaded from the table in your query? Commented Jan 24, 2014 at 15:06
  • Where does that data (array) come from? Can you modify that code? Commented Jan 24, 2014 at 15:07
  • @Styphon - I cannot change the order in which the columns are added to the $columns array (they are added by 3rd party plugins for Wordpress). However I can change the order in which they are output. Commented Jan 24, 2014 at 15:09

6 Answers 6

4

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

Sign up to request clarification or add additional context in comments.

1 Comment

Spot on, even adds the ability to do the job with different keys. Thanks.
1

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

Comments

1

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

Comments

1

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
)

Comments

-1

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

Comments

-1

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!

2 Comments

Exactly. If anyone wants a hint, take a look here. ;)
Thanks, but understanding logic is the easy part. Not what I'm looking for in this instance.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.