How can i make this function faster and without "do"?

I’m trying to create a function that reads one string or a vector of strings from a vector of bytes and also return where it stopped reading in the file:

/The first byte of a string is the length of the string.

/When its a vector,the first 3 bytes have irrelevant information(2 bytes of an ID,1 byte of a constant) while the the 4th and 5th have the size of the vector(the number of strings). 

/file is the byte vector

/index where the (string/vector of strings) starts in the file

/vector boolean saying if its a vector or not

.LTD.getStr:{[file;index;vector]

    $[vector;[size:256 sv file[index+4 3];index+:5];[size:1]];

    r:enlist ();

    do[size;len:5h$file[index];r,:10h$file[1+index+til len];index+:1+len;];

    :(1_r;index);

 }

The function above is working perfectly but I’m trying to get rid of the “do”.

I tryed like this:

.LTD.getStr2:{[file;index;vector]

    $[vector;[size:256 sv file[index+4 3];index+:4];[size:1;index-:1]];

    r:size#();  

    r: r:: 10h$file[1+index+til len:5h$file[index+:1+len]]

    :(r;index);

 }

But this function only creates a vector with the first string in every element of the variable “r”.

Might help to post an example file or dummy data so we can reproduce

file:0x000000;

a:(“T1”;“TE2”;“TES3”;“TEST4”;“TEST 5”;“testing”;“testing sucess”;“”;“”);

size:reverse 6_0x0 vs count a /size of the vector in 2 bytes  little endian;

file,:size;

i:0;

do[count a;file,:4h$count a[i];file,:4h$a[i];i+:1];

You can create a dummy data with the code above where the vector of strings to be returned is in “a”.You can change whats in the variable “a” as long as it stays a vector of strings.

All the strings need to have less than 256 characters.

The vector needs to have less than 65535 elements.

Or you can just use this one which was created with the “a” above:

file:0x0000000900025431035445320454455333055445535434065445535420350774657374696e670e74657374696e67207375636573730000000000000000000000

The function should return the vector of Strings and where it stopped reading(in this case it would be the same as the count of “file”).

When its not vector,it returns a vector of strings with one element

Here a few examples for this case:

When its a vector:

getStr[file;0;1b]

(“T1”;“TE2”;“TES3”;“TEST4”;“TEST 5”;“testing”;“testing sucess”;“”;“”);

55

When its only one string:

getStr[file;5;0b]

,“T1”

8

getStr[file;8;0b]

,“TE2”

12

Em segunda-feira, 24 de agosto de 2015 18:01:53 UTC-3, Carlos Eduado Siestrup escreveu:

I’m trying to create a function that reads one string or a vector of strings from a vector of bytes and also return where it stopped reading in the file:

/The first byte of a string is the length of the string.

/When its a vector,the first 3 bytes have irrelevant information(2 bytes of an ID,1 byte of a constant) while the the 4th and 5th have the size of the vector(the number of strings). 

/file is the byte vector

/index where the (string/vector of strings) starts in the file

/vector boolean saying if its a vector or not

.LTD.getStr:{[file;index;vector]

    $[vector;[size:256 sv file[index+4 3];index+:5];[size:1]];

    r:enlist ();

    do[size;len:5h$file[index];r,:10h$file[1+index+til len];index+:1+len;];

    :(1_r;index);

 }

The function above is working perfectly but I’m trying to get rid of the “do”.

I tryed like this:

.LTD.getStr2:{[file;index;vector]

    $[vector;[size:256 sv file[index+4 3];index+:4];[size:1;index-:1]];

    r:size#();  

    r: r:: 10h$file[1+index+til len:5h$file[index+:1+len]]

    :(r;index);

 }

But this function only creates a vector with the first string in every element of the variable “r”.

You can use this form of scan instead of do

MonadicFunction[numberOfIterations;seedValue]

This makes the vector forms a little quicker but is not quicker for the single string case. You might be better off having two functions, each one optimised for the use case and then a wrapper to choose the correct one.

Something like this (I haven’t really altered your logic):

f:{r:10h$1_'-1_cut[;x] i:{y+1+5h$x y}[x:(n:5+y)_x][256 sv x y+4 3;0];
    (r;n+last i)};

f2:{(enlist 10h$n#(y+1)_x;1+y+n:5h$x y)};

getStr2:{$[z;f;f2][x;y]};

 
q)\ts do[100000;a:getStr[file;0;1b]]
1729 1200
q)\ts do[100000;b:getStr2[file;0;1b]]
1205 1616
q)a~b
1b

 
q)\ts do[100000;a:getStr[file;5;0b]]
232 960
q)\ts do[100000;b:getStr2[file;5;0b]]
137 960
q)a~b
1b

Terry