Monday, 20 February 2012

Mel: Query part of a string, given its index and separator: PART 2

Update to previous post (here), needed to grab a range of items from a string given a separator and index/range (supports reverse and extended indexing).
I do have a horribly sneaky suspicion there is already a built in command for this...
Will work with ranges given as "0", "-1", "0:","-2:", ":2", ":-2", "1:3" and "-3:-1" etc.
// get an item from a string given the string, separator and index number/range as string (supports reverse indexing) //ld_getName "L_test_me_out_bind_jnt" "_" "2:-1" ; global proc string ld_getName(string $obj,string $separator,string $index) { string $mulBuffer[],$indBuffer[],$name ; int $range[],$start,$end ; tokenize $index ":" $mulBuffer ; $range[0]=int($mulBuffer[0]) ; if(startsWith($index,":")) { $mulBuffer[1]=$range[0] ; $range[0]=0 ; } else if(endsWith($index,":")) $mulBuffer[1]=-1 ; tokenize $obj $separator $indBuffer ; $start=$range[0] ; if($range[0]<0) $start=size($indBuffer)-(abs($range[0])) ; if(size($mulBuffer)>1) { $range[1]=int($mulBuffer[1]) ; $end=$range[1] ; if($range[1]<0) $end=size($indBuffer)-abs($range[1]) ; if($end>(size($indBuffer)-1)) return "" ; $name=$indBuffer[$start] ; for($n=($start+1);$n<$end;$n++) $name+=$separator+$indBuffer[$n] ; } else { if($start<0) $name=$indBuffer[size($indBuffer)-int(abs($start))] ; else $name=$indBuffer[$start] ; } return $name ; } Would appreciate any feedback (I know how much simpler this is in python, was curious how simple it was to do in mel).
Python, i think, would handle like this:
"L_test_me_out_bind_jnt".split("_")[2:-1]

2 comments:

  1. I think I'd dump the idea of specifying indexes as one string, and reduce some code for clarity, like this..
    http://pastebin.com/XBpR7kKW

    indexes in my case specify not the separator, but the tokens themselves, meaning that 0..-1 would grab original string, while 1..-1 would grab from first delimiter to the end, and 0..-2 would grab from start till last delimiter. Same should work for -3..-1, etc.

    Should probably check for start<end as well, as I look at it.

    ReplyDelete
  2. Specifying the tokens was actually my preference, (only need to change "for($n=($start+1);$n <= $end;$n++)", but after looking how python treated a range with a reverse index, I thought if I was attempting to mimic something, I might as well mimic as closely as possible, and you could grab entire string through "0:", so "0:-1" would behave the same as it does in python.
    The indexes as a string does annoy me, but I did like the use of "2:" or ":-3", but I suppose, dumping it to separate ints AND specifying the tokens rather than separator, would be the better solution all round.

    Yeah I did have the check for that until I wanted to query "-3:-1", but I just need to check for neg's and flip the condition.
    Cheers

    ReplyDelete