//Title: List Shifting
//Credit to: Foomer
//Contributed by: Foomer
// List shifting causes the entire list to shift so that the item
// specified in the argument becomes the first item in the list,
// while the order of the list remains the same. Example:
// Original: A, B, C, D, E, F, G, H, I
// ListShift(list, list.Find("E"))
// List Now: E, F, G, H, I, A, B, C, D
// This could be used if you want to work your way through a list
// of objects one at a time, but you always have to find out what
// the current 'next' object in the list is, including checking
// to see if the current object is the last object in the list.
proc/listshift(list/L, pos)
if(!L) return
if(pos == 1)
return L // nothing to shift
if(pos < 0 || pos > L.len)
CRASH("Invalid position: [pos] of [L.len]")
for(var/i=1, i<pos, i++)
var/x = L[1]
L -= L[1]
L += x
return L
// Sample Implementation:
var/list/testlist = list("A","B","C","D","E","F","G","H","I",)
mob/verb/TestListShift(position as num)
world << "Test list shifted by [position]:"
var/list/L = listshift(testlist, position)
for(var/i in L)
world << i
// Feel free to contribute a better version if you feel inclined to make one.
ID:195068
![]() Jun 14 2007, 11:36 am (Edited on Jun 14 2007, 11:43 am)
|
|
The main problem I have with both methods of this shown thus far is that they also modify the original list (in addition to returning the modified list). In other words, if you examine testlist after calling TestListShift(), you'll notice that it has been shifted.
My other issue is that I personally prefer to leave error-checking to the user, out of the implementation. Good documentation mentioning what valid inputs are should suffice in this case. For example, consider what yours essentially does in this case: proc/ShiftSome(list/L, shiftCt=1) Given all of your error-checking, it essentially expands to this: proc/ShiftSome(list/L, shiftCt=1) You'll notice that all 4 of those conditions will be redundantly checked for the 10 iterations of its calling, even though the second argument being passed (2) is constant and qualifies, and the list is checked prior to the loop for validity so that it can be used in the output statement. Here's how I would remake the proc, personally: //Title: List Shifting (rev.) |
I've enabled negative and greater-than-L.len positions for relative value. -1 will be the end, -2 will be second to last, etc...