How to count occurance in livecode? - livecode

I need to count the number of occurance of word in the array from the field "MytextField". The array consist of more than 9000 lines and the text in field "MytextField" consist of more than 10000 lines. I am using the following code and it works fine but need so much time.
put the number of lines of (the keys of myArray) into myArrayL
repeat with i = 0 to myArrayL
put myArray[i] into k
split k by colon
put k[1] into searchStr
put k[2] into replaceStr
repeat for each line iword in Tex
if iword contains searchStr then
add 1 to tmp
put tmp & " " & searchStr & cr into sam
end if
--delete word iword of Tex
if iword contains replaceStr then
add 1 to tmp1
put tmp1 & " " & replaceStr & cr into sam1
end if
--delete word iword of Tex
end repeat
put sam after slu
put 0 into tmp
put "" into sam
put sam1 after slu1
put 0 into tmp1
put "" into sam1
end repeat
answer slu1
answer slu
Is it any way to decrease the time consumption?
How to change this code with more speed

Try using offsets, which should be faster than examining every word:
put fld "MytextField" into tText
set the itemdel to colon
repeat for each element e in myArrayL
put item 1 of e into searchStr
put 0 into tSkip
repeat
get wordOffset(searchStr,tText,tSkip)
if it = 0 then exit repeat
add it to tSkip
add 1 to tCountArray[searchStr]
end repeat
end repeat
That counts the search words and puts the counts into an array. You can alter it a bit and run it again if you need to count the replacement words too. Don't count the search words and replacement words in the same repeat loop, you'll get incorrect results. I don't know if this will be much faster than your original script because the repeat loop has to run twice if you want both search and replacement word counts.
After the arrays are made, you can use the combine command to quickly show the counts.

Try the repeat for each element construct instead. It is generally faster in situations like this than repeat with i = x to y forms.
repeat for each element thisElement in myArray
# your loop logic here
end repeat

Related

How can I separate all the characters of a word into separate fields?

I have a random word generation script that works perfectly. I also have a few single character-width fields, exactly the same amount of them as the longest possible word that can be generated. Below each field I have a line that would resemble an underscore. Each field has a unique id, numbered from one like so: "letter1", "letter2".... and so on. Likewise, each line has the id of "line1", "line2", and so on.
Now that I've set the stage, here is what I want to happen. On the opening of the card, I want all of the letter fields to hide as I will have them show individually outside this subroutine. I then want all of the lines to hide, and then only the amount of lines that are required for the random word should show again. (The same number as length(randomword) from left to right.) Now, the random word should be looped through and the first character should be put into the field "letter1", and the second into "letter2", and so on. The word will change each time the card is opened, so it is important that this is not bruteforced (which unfortunately, myself having two weeks experience with LiveCode, is the only thing I know concretely how to do).
Could someone with more experience do me a solid and provide the code I would need to do this, and the location I should put the code in? (the card? the letter fields? I really don't know at this point).
I am happy to provide further description if I have not been articulate about my problem.
Try this (my LiveCode is a bit rusty):
on openCard
//Put your word generation script here
put 0 into amtOfLines
put 0 into amtOfLetters
repeat until amtOfLines is 6 //Replace 6 with the amount of lines
add 1 to amtOfLines
put "line" & amtOfLines into x
set the visible of graphic x to false
end repeat
repeat until amtOfLetters is 6 //Replace 6 with the amount of fields
add 1 to amtOfLetters
put "letter" & amtOfLetters into x
set the visible of field x to false
end repeat
put 0 into amtOfLines
put 0 into amtOfLetters
repeat until amtOfLines is length(randomword)
add 1 to amtOfLines
put "line" & amtOfLines into x
set the visible of graphic x to true
end repeat
repeat until amtOfLetters is length(randomword)
add 1 to amtOfLetters
put "letter" & amtOfLetters into x
set the visible of field x to true
end repeat
put 0 into amtOfChars
repeat until amtOfChars is length(randomword)
add 1 to amtOfChars
put "letter" & amtOfChars into x
set the text of field x to char amtOfChars of randomword
end repeat
end openCard
This would go in the card script.
EDIT: Fixed some errors.
This would go into the card script:
on setup pRandomWord
put 6 into tNumObjs -- or however many fields there are
put length(pRandomWord) into tLen
repeat with x = 1 to tNumObjs
hide fld ("letter"&x)
if x <= tLen then
put char x of pRandomWord into fld ("letter"&x)
show grc ("line"&x)
else
hide grc ("line" & x)
end if
end repeat
end setup
When you want to use it, put the random word into a variable and call the setup handler like this:
setup randomWord
This does everything in a single repeat loop. The random word is passed to the setup handler in the parameter "pRandomWord".

How to count the sum of numbers in a field in Livecode

I have an Scrolling Field and it's congaing number and word separated by space.
I want to find the sum of number (eg: 5 USA &CR 5 Uk)
on mouseUp
if the field "CC" is not empty then//here "CC" is an Scrolling field and it's containing the content
put 0 into aa
put fld "CC" into myData
split myData by CR
put the number of lines of (the keys of myData) into myArraylength
repeat with i = 1 to myArraylength
put 0 into zo
put myData[i] into y
split y by space
put y[1] into searchStr
if y[1]is not a number then
put 0 into var1
else
put searchStr into vari
put vari &comma after ss1
end if
end repeat
answer ss1
put sum(ss1) into aa1
answer aa1
put ss1 into second1
split second1 by comma
else
answer "List is Empty"
end if
end mouseUp
Assuming the text in your scrolling field is formatted consistently as in your example:
5 USA
5 UK
4 EUR
etc.
You can do something like this:
put fld "myScrollingFld" into tList
put 0 into tTotal
repeat for each line tLineContents in tList
put word 1 of tList into tNum
if tNum is a number then add tNum to tTotal
end if
on mouseUp
repeat for each word thisWord in fld "Myfield"
if thisWord is a number then add thisWord to tSum
end repeat
answer tSum
end mouseUp

How to compare two scrolling field

How to compare two scrolling field(I have two fields one containing some text and another containing search string & Replace string these are separated by colon. I want to search each word in the first Scrolling field with search string in second scrolling field, If search strings is found in first scrolling field then return the particular words and count of search string in first scrolling field)
on mouseUp
put the fld "MytextField" into myHtmll
put the field SRText into myArrayT
split myArrayT by CR
put the number of lines of (the keys of myArrayT) into myArrayl
repeat with j=1 to myArrayl
put myArrayT[j] into k
split k by colon
put k[1] into searchStr1
put k[2] into replaceStr1
end repeat
repeat for each word dd in field "MytextField"
if dd contains searchStr1 then
--put Wordss after mm
--answer searchStr1
answer ok
end if
answer searchStr
end repeat
end mouseU
Here "MytextField" is the first scrolling field
Here "SRText" is the second scrolling field
on mouseUp
set the caseSensitive to true
put the field SRText into myArrayT
split myArrayT by CR
put the number of lines of (the keys of myArrayT) into myArrayl
put 0 into tmp
repeat for each key j in myArrayT
put myArrayT[j] into k
split k by colon
put k[1] into searchStr1
put the field "MytextField" into sss
repeat for each word ass in sss
if ass contains searchStr1 then
add 1 to tmp
put ass after sam
end if
end repeat
end repeat
answer sam
answer tmp
end mouseUP

How to display repeated words in an array using LiveCode

I am a beginner in LiveCode. How I display repeated words and their count in an array. Is it possible?
global ar
on mouseUp
--answer ar
//ar contain some text
put ar into s1
split s1 by CR
put the number of lines of (the keys of s1) into s2
repeat for each word k in s1
put s1[k] into k1
split k1 by CR
end repeat
answer k1[1]
end mouseUp
repeat for each key j in myArrayT
put myArrayT[j] into k
split k by colon
Make a field and fill it with a bunch of words, many of which repeat one or more times. Name that field "wordList". Now in a button script:
on mouseUp
get fld "wordList"
repeat for each word tWord in it
add 1 to wordCount[tword]
end repeat
combine wordCount by return and comma
answer wordCount
end mouseUp

Scorlling filed is empty but it display some string why?

I have two Scrolling field and one containing some text and another containing some words. eg. (s1:s2) separated by colon my objective is to find how many words in the second Scrolling are appearing in first Scrolling field. (eg: if s1 is appearing in first scrolling field then it shows s1,1 it means s1 appearing one time). While executing my code it's work but if my first scrolling field is empty it shows some text also some times it takes some words in the first field. (eg:\documentclass)this word is not in 2'nd field.
I am using the following code.
global ar
global sam
on mouseUp
--set the caseSensitive to true
put 0 into tmp
put empty into sam
put the field SRText into myArrayT
split myArrayT by CR
put the number of lines of (the keys of myArrayT) into myArrayl
repeat for each key j in myArrayT
put myArrayT[j] into k
split k by colon
put k[1] into searchStr1
put the field "MytextField" into sss
repeat for each word ass in sss
if ass contains searchStr1 then
add 1 to tmp
put ass & CR & CR after sam
put sam into ar
end if
end repeat
end repeat
answer sam
answer tmp
--answer sa
end mouseUP
on mouseDown
answer ar
put ar into ss
get ss
repeat for each word tWord in it
add 1 to wordCount[tword]
end repeat
combine wordCount by return and comma
answer wordCount
--put empty into sam
end mouseDown
You really should use quotes around field names. I promise you'll realise some day, that you have been shooting yourself in the foot all the time.
Don't use the in front of object references,
field "Field Name"
button "Field name"
but do use the in front of property references:
the number of lines of fld "Field Name"
the text of fld "Field Name"
the name of this stack
There really use no reason for your obsession with arrays. Stop using arrays when you don't need them! It just makes things overly complicated and slow.
I have modifed your mouseUp handler. I didn't look at your mouseDown handler. I believe your mouseUp handler should look like this:
on mouseUp
--set the caseSensitive to true
put 0 into tmp
put empty into sam
repeat for each line k in fld "SRText"
set the itemDel to colon
put item 1 of k into searchStr1
repeat for each word ass in field "MytextField"
if ass contains searchStr1 then
add 1 to tmp
put ass & colon & tmp & cr after sam
end if
end repeat
put 0 into tmp
end repeat
put sam
end mouseUp
The script above is based on your approach and I really don't understand why you would do it this way and what you would do with the result. The script below is probably much more efficient and it seems more useful to me.
on mouseUp
// I assume fld SRText contains a list similar to
// "abc:1" & cr & "bcd:2" & cr & "cde:1" & cr & "def:4"
put fld "SRText" into myData
split myData by cr and colon
put the keys of myData into myData
// myData is not an array!
repeat for each word myWord in fld "MytextField"
if myWord is among the lines of myData then
// use an array to store data, not to loop through
if myCounts[myWord] is empty then
put 1 into myCounts[myWord]
else
add 1 to myCounts[myWord]
end if
end if
end repeat
combine myCounts by cr and colon
put myCounts
end mouseUp

Resources