Rearranging array contents

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
User avatar
Skittlewidth
Forum Contributor
Posts: 389
Joined: Wed Nov 06, 2002 9:18 am
Location: Kent, UK

Rearranging array contents

Post by Skittlewidth »

Can someone help me get my head around this?

Say a user generates a list - in this case its a list of questions.

Each question is added to an array, which dictates the order the questions are presented to the end user. ie. the designer of the survey currently has to enter the questions in the order in which they want the end user to see them.

But say the user makes a mistake and needs to reorder the list?

I want to give the user the list of questions with "move up" and "move down" links to the right of them which will ultimately affect the position in the array, but can't think where to start in coding it.

Should I attempt to reassign the keys or swap the values, and how? :?:
User avatar
neophyte
DevNet Resident
Posts: 1537
Joined: Tue Jan 20, 2004 4:58 pm
Location: Minnesota

Post by neophyte »

I would make the arrows buttons with a value equal to their position in array and the form. So the person pushes the button and the button registers two values: up or down and current ordered position. From that you can calculate the position. Moving them up and down in the array will be slightly more difficult. But it might look something like:

Code: Select all

if(isset($_POST['up'])){
     //The current position of question is stored in  $_POST['up'] or $_POST['down']
     //split the array on the position  to insert
    // push the value on to the bottom of one of the arrays
    //combine the array's together
   //return the completed array
}
if (isset($_POST['down'])){
  //same as above

}
That's how I'd do it. But I'd be interested in seeing how others might attempt this too.
User avatar
Skittlewidth
Forum Contributor
Posts: 389
Joined: Wed Nov 06, 2002 9:18 am
Location: Kent, UK

Post by Skittlewidth »

Sounds like a good idea.

I've just found this custom function on php.net that will allow users to delete items from the middle of the array, so thats that possibility sorted, and I may be able to adapt that to help with rearranging somehow:

Code: Select all

function array_remove() {
   if ($stack = func_get_args()) {
     $input = array_shift($stack);
     foreach ($stack as $key) {
       unset($input[$key]);
     }
     return $input;
   }
   return false;
  }
Your idea sounds much more logical though, so I will try that first. 8)
User avatar
Jenk
DevNet Master
Posts: 3587
Joined: Mon Sep 19, 2005 6:24 am
Location: London

Post by Jenk »

Would this be of any help?

Code: Select all

<?php

function & array_switch(&$arr, $x)
{
	$arr2 = array_slice($arr, $x, 2, true);	
	rsort($arr2);
	array_splice($arr, $x, 2, $arr2);
}

$arr = array('1', '2', '3', '4', '5');
$pos = '1';

print_r($arr);

array_switch($arr, $pos)

print_r($arr);

?>
$pos can be defined from $_GET and on the form, each record has an "up" and a "down" button I take it, so when echoing the links, for "up"/"down" echo it like:

Code: Select all

echo '<a href="http://www.yoursite.com/page.php?pos=' . ($i - 1) . '">Up!</a>';
echo '<a href="http://www.yoursite.com/page.php?pos=' . $i . '">Down!</a>';
User avatar
Skittlewidth
Forum Contributor
Posts: 389
Joined: Wed Nov 06, 2002 9:18 am
Location: Kent, UK

Post by Skittlewidth »

That's almost perfect Jenk, thanks. My only issue is that if you move one item up and then go to reorder another item, it re-sorts the whole array before moving the second item.

This may just be due to my hurried implementation of it though. I'll take another look.
Thanks again.
User avatar
Skittlewidth
Forum Contributor
Posts: 389
Joined: Wed Nov 06, 2002 9:18 am
Location: Kent, UK

Post by Skittlewidth »

Yep, was just me! Works a treat. 8)

Edit: Why is it that once the array has reached its exact reverse of where it started this code ceases to work? I can't see why it should.
josh
DevNet Master
Posts: 4872
Joined: Wed Feb 11, 2004 3:23 pm
Location: Palm beach, Florida

Post by josh »

I would have select box's next to each item, numbered 1-X where X is the total # of items, and let them re-order everything at once then hit a button for the changes to take effect, either that or code it with AJAX so the items re-order themselves live (with the up and down buttons). You can also use array_multisort for more complex re-ordering.
User avatar
Skittlewidth
Forum Contributor
Posts: 389
Joined: Wed Nov 06, 2002 9:18 am
Location: Kent, UK

Post by Skittlewidth »

The select box idea would work, but it might not be easy on the user with a long list of items. I might give it a go later.

Back to Jenk's function though, can anyone explain why when I run the code, if I move an item "up", my next move cannot be "down" on the same item. It will only move again in the same direction. Once the array has been completely reversed i.e from 12345 to 54321 none of the items will move at all.

Also:

Code: Select all

$arr2 = array_slice($arr, $x, 2, true);
I know the "true" parameter is only available from PHP5, and I'm going to need to run this on PHP4, (although I am currently testing it on PHP5). The code runs exactly the same with the same problems with or without "true" anyway... or am I overlooking something?
User avatar
Skittlewidth
Forum Contributor
Posts: 389
Joined: Wed Nov 06, 2002 9:18 am
Location: Kent, UK

Post by Skittlewidth »

Ok, I have it working perfectly now:

Code: Select all

function array_switch(&$arr, $x)
{
    $arr2 = array_slice($arr, $x, 2);    
    $arr2 = array_reverse($arr2);
    
    array_splice($arr, $x, 2, $arr2);
   
    return $arr;
}
I simply switched the rsort for array_reverse and I can rearrange the array to my hearts content. :D
User avatar
Jenk
DevNet Master
Posts: 3587
Joined: Mon Sep 19, 2005 6:24 am
Location: London

Post by Jenk »

Only just seen this again, was my bad for using rsort as that orders in reverse by value not position :)
User avatar
Skittlewidth
Forum Contributor
Posts: 389
Joined: Wed Nov 06, 2002 9:18 am
Location: Kent, UK

Post by Skittlewidth »

Yep, that's what I eventually realised. Thanks for the function though. :)
Post Reply