Reputation: 12047
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
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
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
)
Upvotes: 4
Reputation: 3566
In general:
Split your current array into two parts ($larray, $rarray
)- before and after place you want to insert your key (for example using foreach
).
Add your new key to the end of left side, for example $larray = $larray + array('key' => 'value')
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
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
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
Reputation: 832
You can do that with array_splice
look here or use a custom sort function.
Upvotes: -1