Page 1 of 1

Rearranging array contents

Posted: Fri Dec 02, 2005 8:23 am
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? :?:

Posted: Fri Dec 02, 2005 8:40 am
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.

Posted: Fri Dec 02, 2005 8:57 am
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)

Posted: Fri Dec 02, 2005 9:13 am
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>';

Posted: Fri Dec 02, 2005 9:42 am
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.

Posted: Fri Dec 02, 2005 9:51 am
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.

Posted: Fri Dec 02, 2005 11:46 am
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.

Posted: Mon Dec 05, 2005 3:52 am
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?

Posted: Mon Dec 05, 2005 8:24 am
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

Posted: Mon Dec 05, 2005 8:44 am
by Jenk
Only just seen this again, was my bad for using rsort as that orders in reverse by value not position :)

Posted: Mon Dec 05, 2005 8:54 am
by Skittlewidth
Yep, that's what I eventually realised. Thanks for the function though. :)