Concatenate variable-length-strings as table - string

I am fetching an array of data from SQL, and then concatenating them as strings for display. The function looks like this:
function FetchTopStats( Conn, iLimit )
local sToReturn = "\tS.No. \t UserName \t Score\n\t"
SQLQuery = assert( Conn:execute( string.format( [[SELECT username, totalcount FROM chatstat ORDER BY totalcount DESC LIMIT %d]], iLimit ) ) )
DataArray = SQLQuery:fetch ({}, "a")
i = 1
while DataArray do
sToReturn = sToReturn..tostring( i ).."\t"..DataArray.username.." \t "..DataArray.totalcount.."\n\t"
DataArray = SQLQuery:fetch ({}, "a")
i = i + 1
end
return sToReturn
end
This gives me an output like:
S.No. UserName Score
1 aim 6641
2 time 5021
3 Shepard 4977
and so on. I am thinking of using a string.format function, to have a display as follows:
S.No. UserName Score
1 aim 6641
2 time 5021
3 Shepard 4977
But, I am totally out of ideas on how to have this. The only option coming to my mind is checking string length of username, and then applying \t accordingly. That, I want to use at the very last.

Well, you need to either find out the maximum length of username thus making the algorithm 2-pass, or limit it to some arbitrary (but reasonable) size and unconditionally chop off the tails of too long strings. Once you have the column width, you can use left or right aligned format strings:
> print(string.format("|%-10d|%-20s|%10d|", 1, "Shepard", 9000))
|1 |Shepard | 9000|
Also, for large tables consider using table.concat for building the final output: it's considerably faster than repeatedly appending strings (refer to the Chapter 11.6 of PIL for explanation).

Related

Concat two variable values with space in Lua

I have a string I am trying to build out of a variable containing strings and a space and an another string(integer.) The string needs to consist of index numbers based on the number of elements in a table called "master_table" The first time through the variable "indexes_to_process" is nil. I am trying to use the stanza below to set it. However, it still contains a nil value even through x is set correctly. I am sure this is some syntax gotcha that I am drawing a blank on. I've tried several alterations to this and nothing works. Would appreciate any suggestions. The goal is to have a variable that contains the following:
"1 2 3 4 5 6 7 8 9 10 11 12 13 14 15" and so on. I am doing this so I can have a variable control loop of thousands to millions of index numbers. . . .this was my solution to address slow table processing after 100K elements. Ie., I want to be able to add index numbers to the variable "indexes_to_process" so that loop will hit this element. This save me processing empty elements in the table because the processing through all table elements takes too long after I get into the 100K range and I have maybe 10K elements that need to be processed.
Thanks in Advance!
if indexes_to_process == nil then
for x = 1,table.maxn(master_table) do
print ("x:"..x) --uncomment for debug
indexes_to_process = (indexes_to_process," ",x)
print ("indexes to process",indexes_to_process) --uncomment for debug
end
end
here are 2 examples:
local master_table = {1,2,3,4,5,6}
local indexes_to_process
-- first
indexes_to_process = table.concat(master_table," ")
print(indexes_to_process)
-- second
indexes_to_process = nil
local temp = {}
for k,v in ipairs(master_table) do
temp[#temp+1] = v .." "
end
indexes_to_process = table.concat(temp)
print(indexes_to_process)
in any case, never glue strings inside a large loop, memory consumption and performance drops, like:
indexes_to_process = indexes_to_process.. " "..x -- bad idea
PS: if you think that the value x can be nil, use:
x = (x or "") .. "text"

Find biggest element in a String with words?

How can I, in ABAP, split a string into n parts AND determine which one is the biggest element? In my solution I would need to know how many elements there are, but I want to solve it for WHATEVER NUMBER of elements.
I tried the below code. And i searched the web.
DATA: string TYPE string VALUE 'this is a string'.
DATA: part1 TYPE c LENGTH 20.
DATA: part2 TYPE c LENGTH 20.
DATA: part3 TYPE c LENGTH 20.
DATA: part4 TYPE c LENGTH 20.
DATA: del TYPE c VALUE ' '.
DATA: bigger TYPE c LENGTH 20.
split: string AT del INTO part1 part2 part3 part4.
bigger = part1.
IF bigger > part2.
bigger = part1.
ELSEIF bigger > part3.
bigger = part2.
ELSE.
bigger = part4.
ENDIF.
WRITE: bigger.
Expected result: Works with any number of elements in a string and determines which one is biggest.
Actual result: I need to know how many elements there are
Here is one way to solve it:
DATA: string TYPE string VALUE 'this is a string'.
TYPES: BEGIN OF ty_words,
word TYPE string,
length TYPE i,
END OF ty_words.
DATA: ls_words TYPE ty_words.
DATA: gt_words TYPE STANDARD TABLE OF ty_words.
START-OF-SELECTION.
WHILE string IS NOT INITIAL.
SPLIT string AT space INTO ls_words-word string.
ls_words-length = strlen( ls_words-word ).
APPEND ls_words TO gt_words.
ENDWHILE.
SORT gt_words BY length DESCENDING.
READ TABLE gt_words
ASSIGNING FIELD-SYMBOL(<ls_longest_word>)
INDEX 1.
IF sy-subrc EQ 0.
WRITE: 'The longest word is:', <ls_longest_word>-word.
ENDIF.
Please note, it does not cover the case if there are more longest words with the same length, it will just show one of them.
You don't need to know the number of splitted parts if you split the string into an array. Then you LOOP over the array and check the string length to find the longest one.
While József Szikszai's solution works, it may be too complex for the functionality you need. This would work just as well: (also with the same limitation that it willl only output the first longest word and no other ones of the same length)
DATA string TYPE string VALUE 'this is a string'.
DATA parts TYPE STANDARD TABLE OF string.
DATA biggest TYPE string.
FIELD-SYMBOLS <part> TYPE string.
SPLIT string AT space INTO TABLE parts.
LOOP AT parts ASSIGNING <part>.
IF STRLEN( <part> ) > STRLEN( biggest ).
biggest = <part>.
ENDIF.
ENDLOOP.
WRITE biggest.
Edit: I assumed 'biggest' meant longest, but if you actually wanted the word that would be last in an alphabet, then you could sort the array descending and just output the first entry like this:
DATA string TYPE string VALUE 'this is a string'.
DATA parts TYPE STANDARD TABLE OF string.
DATA biggest TYPE string.
SPLIT string AT space INTO TABLE parts.
SORT parts DESCENDING.
READ TABLE parts INDEX 1 INTO biggest.
WRITE biggest.
With ABAP 740, you can also shorten it to:
SPLIT lv_s AT space INTO TABLE DATA(lt_word).
DATA(lv_longest) = REDUCE string( INIT longest = `` FOR <word> IN lt_word NEXT longest = COND #( WHEN strlen( <word> ) > strlen( longest ) THEN <word> ELSE longest ) ).
DATA(lv_alphabetic) = REDUCE string( INIT alph = `` FOR <word> IN lt_word NEXT alph = COND #( WHEN <word> > alph THEN <word> ELSE alph ) ).
If "biggest" means "longest" word here is the Regex way to do this:
FIND ALL OCCURRENCES OF REGEX '\w+' IN string RESULTS DATA(words).
SORT words BY length DESCENDING.
WRITE substring( val = string off = words[ 1 ]-offset len = words[ 1 ]-length ).

How to get lines count in string?

On the whole, I get a string from JSON pair which contain "\n" symbols. For example,
"I can see how the earth nurtures its grass,\nSeparating fine grains from lumpy earth,\nPiercing itself with its own remains\nEnduring the crawling insects on its surface.\nI can see how like a green wave\nIt lifts the soil, swelling it up,\nAnd how the roots penetrate the surrounding mulch\nHappily inhaling the air in the sky.\nI can see how the light illuminates the flowers, -\nPouring itself into their tight buds!\nThe earth and the grass – continue to grow!\nDrowning the mountains in a sea of green...\nOh, The power of motion of the young,\nThe muscular pull of the plants!\nOpening up to the planet, the sun and to you,\nBreaking through the undergrowth to the fresh spring air!"
This string is a poetry for some picture.
Now I need to resize my display.newText object according to text length.
Here is how I see to do that:
Get number of lines (number of "\n" + 1, because where is no "\n" in the end)
In for loop get the longest line
Set display.newText object's size. May be using fontSize for calculating coefficient...
Question is: How to get number of lines?
To get the number of '\n' in a string, you can use string.gsub, it's used for string substitution, but it also returns the number of matches as the second return value.
local count = select(2, str:gsub('\n', '\n'))
or similar:
local _, count = str:gsub('\n', '\n')
This is apparently way faster than #Yu Hao's two solutions
local function get_line_count(str)
local lines = 1
for i = 1, #str do
local c = str:sub(i, i)
if c == '\n' then lines = lines + 1 end
end
return lines
end

Matlab Reading List of List from a Text File as String

I am a Java developer and new to Matlab. I have a file something like that:
Label_X sdfasf sadfl asdf a fasdlkjf asd
Label_Y lmdfgl ldfkgldkj dkljdkljdlkjdklj
Label_X sfdsa sdfsafasfsafasf 234|3#ert 44
Label_X sdfsfdsf____asdfsadf _ dsfsd
Label_Y !^dfskşfsşk o o o o 4545
What I want is:
A vector (array) includes labels:
Label Array:
Label_X
Label_Y
Label_X
Label_X
Label_Y
and a List (has five elements for our example) and every element of list has elements size of delimited strings. I mean
Element Number Value(List of strings) Element size of value list
-------------- ---------------------- --------------------------
1 sdfasf,sadfl,asdf,a,fasdlkjf,asd 6
2 lmdfgl,ldfkgldkj,dkljdkljdlkjdklj 3
3 sfdsa,sdfsafasfsafasf,234|3#ert,44 4
4 sdfsfdsf____asdfsadf,_,dsfsd 3
5 !^dfskşfsşk,o,o,o,o,4545 6
I know it is pretty simple with Java but I don't know how to implement it in Matlab.
PS: What I am doing is that. I have a text file includes tweets of people. First word is label at row, and other words are corresponding words related to that label. I will have a list of labels and another list of list that holds words about each label.
This probably isn't optimal, but it should do the trick
all = textread('test.txt', '%s', 'delimiter', '\n','whitespace', '');
List = cell(size(all));
for i = 1:size(all)
[List{i}.name remain] = strtok(all{i}, ' ');
[List{i}.content remain] = strtok(remain, ' ');
j = 0;
while(size(remain,2)>0)
j = j+1;
List{i}.content = [List{i}.content temp ','];
[temp remain] = strtok(remain, ' ');
end
List{i}.size = j;
end
The best construct for this in Matlab is the cell. Cells can contain one object, of any type, and are typically found in arrays themselves. Something like this should work, and be pretty optimal (Assuming you don't expect more than 10K lines);
output=cell(10000,1); %This should be set to the maximum number of lines you ever expect to have
output_names=cell(size(output));
output_used=false(size(output));
fid=fopen('filename.txt','r');
index=0;
while ~feof(fid)
index=index+1;
line=fgets(fid);
splited_names=regexp(line,'\w*','split');
output{index}=splited_names(2:end);
output_names{index}=splited_names(1);
output_used(index)=true;
end
output=output(output_used);
output_names=output_names(output_used);

Sorting strings in MATLAB like Windows 7 sorts filenames in explorer (respecting numerals mid-string)

What is the best way to sort strings in MATLAB, respecting numerals that could be present mid-string?
The following example illustrates my problem. 401 is a numerically higher value than 6. Therefore, the Ie401sp2 string should be listed after the Ie6 string when sorting in ascending order. In this example, note how the following strings, which contain numerals, are sorted.
---Matlab--- (Not sorting the way I want)
Ie4_01
Ie4_128
Ie401sp2
Ie5
Ie501sp2
Ie6
---Windows 7--- (The way I want MATLAB to sort)
Ie4_01
Ie4_128
Ie5
Ie6
Ie401sp2
Ie501sp2
Windows 7 respects the relative values of the numerals that appear mid-string. What is the best way to do this in Matlab? I am trying to avoid going off on a minor tangent to reinvent the wheel.
This is a bit of a hacky version, but it roughly works:
function x = sortit(x)
% get a sortable version of each element of x
hacked_x = cellfun( #iSortVersion, x, 'UniformOutput', false );
% sort those, discard the sorted output
[~, idx] = sort( hacked_x );
% re-order input by sorted order.
x = x(idx);
end
% convert a string with embedded numbers into a sortable string
function hack = iSortVersion( in )
pieces = regexp( in, '(\d+|[^\d]+)', 'match' );
pieces = cellfun( #iZeroPadNumbers, pieces, 'UniformOutput', false );
hack = [ pieces{:} ];
end
% if a string containing a number, pad with lots of zeros
function nhack = iZeroPadNumbers( in )
val = str2double(in);
if isnan(val)
nhack = in;
else
nhack = sprintf( '%030d', val );
end
end

Resources