Forum Moderators: coopster & phranque

Message Too Old, No Replies

Rearrange perl array elements.

Depends on if element already exist.

         

mdharrold

2:32 am on Apr 20, 2002 (gmt 0)

10+ Year Member



How do you move, for example, element[3] to element[0] and bump everything else down?

I want to rearrange array elements based on user input.

foreach $element (@array)
{if ($element == $input) # if $input exist in @array
{move $element to first postition and rearrange remaining}
else # if $input does not exist in @array
{unshift @array, $input;}}

Understand? It should work similar to the "recent post" on this site.

Josk

12:32 pm on Apr 20, 2002 (gmt 0)

10+ Year Member



why not use a hash? mapped:
$myvalue => $idealOrder where the order is assigned by the user? I suppose you could do this with an array, but I would have thought sorting on whatever the value of the keys would be simpler than doing $array[$newpos] = $array[$oldpos]

sugarkane

4:20 pm on Apr 22, 2002 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Using a combination of splice and unshift with a counter for the element number will have the effect you're looking for:

[perl]
$counter=0;
foreach $element (@array) {
if ($element == $input) { # check if this element matches the input
splice @array,$counter,1; # if so, remove it...
unshift @array, $input; # ...and put it to the front
$flag=1; # set a flag so we know we've found a match
}
$counter++; # increment the counter
}

# next check if we've found a match, if not add the input to the start of @array
unless ($flag) {
unshift @array, $input;
}
[/perl]

Hopefully that'll get you up and running, although it's untested code...

Josk

6:20 pm on Apr 22, 2002 (gmt 0)

10+ Year Member



hmmm...that looks *way* more elegent than my idea! Must read up on how it works, though...

mdharrold

10:30 pm on Apr 22, 2002 (gmt 0)

10+ Year Member



I went a different way down a similar path.

foreach $element (@array)
{if ($element ne "$input")
{push @new_array, $element;}}
unshift @new_array, $input;

Seems to be working.

sugarkane

9:46 am on Apr 23, 2002 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Good solution mdharrold, but both mine and yours are quite inefficient if a large array is involved, as they loop through the entire array regardless of whether the matching element is at the end or beginning.

Something like this should be more efficient, using 'last' to break out of the loop once a match is found:

[perl]
for ($i=0; $i < $#array; $i++) {
if ($array[$i] == $input) {
splice @array,$i,1; # remove element if a match found
last;
}
}
unshift @array, $input; # add $input to the start of the array
[/perl]