How to split multiple sentences in part by part in Dart, flutter? - flutter

I want to split a paragraph with multiple sentences part by part. Specifically, I want to show 1st sentence in a Text widget and then remaining of the sentence in another Text widget. How can I achieve this?
var str = 'Taste the crunchy and spicy goodness of our potato chips! Our chips are sure to tantalize your taste buds, leaving you wanting more! And with their irresistible flavor, you won't be able to resist the temptation to indulge. So why not grab a bag today and experience the deliciousness of our potato chips? You won't regret';
var parts = str.split(' ');
var prefix = parts[0].trim();
var prefix1 = parts[1].trim();
print(prefix); // Taste
print(prefix1); // the
It prints out word by word but not sentence by sentence..

If your sentences are separated by periods (.), you can do something like this:
String str = "first. second. third.";
// get the position of the first period
int index = str.indexOf(".");
// get first sentence
var firstPart = str.substring(0, index + 1).trim();
// get the rest of sentences
var secondPart = str.substring(index + 1).trim();
update:
if you sentences can end with (. or ! or ?), you can use a RegEx as an argument to indexOf method
int index = str.indexOf(RegExp(r'[\.\?\!]'));

Related

Index of word in string 'covering' certain position

Not sure if this is the right place to ask but I couldn't find any related or similar questions.
Anyway: imagine you have a certain string like
val exampleString = "Hello StackOverflow this is my question, cool right?"
If given a position in this string, for example 23, return the word that 'occupies' this position in the string. If we look at the example string, we can see that the 23rd character is the letter 's' (the last character of 'this'), so we should return index = 5 (because 'this' is the 5th word). In my question spaces are counted as words. If, for example, we were given position 5, we land on the first space and thus we should return index = 1.
I'm implementing this in Scala (but this should be quite language-agnostic and I would love to see implementations in other languages).
Currently I have the following approach (assume exampleString is the given string and charPosition the given position):
exampleString.split("((?<= )|(?= ))").scanLeft(0)((a, b) => a + b.length()).drop(1).zipWithIndex.takeWhile(_._1 <= charPosition).last._2 + 1
This works, but it is way too complex to be honest. Is there a better (more efficient?) way to achieve this. I'm fairly new to functions like fold, scan, map, filter ... but I would love to learn more.
Thanks in advance.
def wordIndex(exampleString: String, index: Int): Int = {
exampleString.take(index + 1).foldLeft((0, exampleString.head.isWhitespace)) {
case ((n, isWhitespace), c) =>
if (isWhitespace == c.isWhitespace) (n, isWhitespace)
else (n + 1, !isWhitespace)
}._1
}
This will fold over the string, keeping track of whether the previous character was a whitespace or not, and if it detects a change, it will flip the boolean and add 1 to the count (n).
This will be able to handle groups of spaces (e.g. in hello world, world would be at position 2), and also spaces at the start of the string would count as index 0 and the first word would be index 1.
Note that this can't handle when the input is an empty string, I'll let you decide what you want to do in that case.

Swift splitting UILabel between two lines

Here's a picture of a UILabel getting split between two lines:
I'm okay with it getting split, but it's getting split awkwardly. Is there any way to distribute the text more evenly between the two lines? I.e. to have three words (no pun intended) on each line in this case. The string is coming from user input, so I need a solution that works for any string (character limit is 40). Also, I'm doing this programatically. Thanks!
Add a linebreak \n to the text where you want the split to happen.
EDIT
Here is a solution that splits the string in roughly half, based on spaces:
var str = "Hello, label, here is some variable text"
let length = str.characters.count // 40
var splitRange = str.range(of: " ", options: String.CompareOptions.literal, range: str.index(str.startIndex, offsetBy: length / 2)..<str.endIndex, locale: nil) // finds first space after halfway mark
var firstLine = str.substring(to: splitRange!.lowerBound) // "Hello, label, here is"
var secondLine = str.substring(from: splitRange!.upperBound) // "some variable text"

How to get the number of real words in a text in Swift [duplicate]

This question already has answers here:
Number of words in a Swift String for word count calculation
(7 answers)
Closed 5 years ago.
Edit: there is already a question similar to this one but it's for numbers separated by a specific character (Get no. Of words in swift for average calculator). Instead this question is about to get the number of real words in a text, separated in various ways: a line break, some line breaks, a space, more than a space etc.
I would like to get the number of words in a string with Swift 3.
I'm using this code but I get imprecise result because the number is get counting the spaces and new lines instead of the effective number of words.
let str = "Architects and city planners,are \ndesigning buildings to create a better quality of life in our urban areas."
// 18 words, 21 spaces, 2 lines
let components = str.components(separatedBy: .whitespacesAndNewlines)
let a = components.count
print(a)
// 23 instead of 18
Consecutive spaces and newlines aren't coalesced into one generic whitespace region, so you're simply getting a bunch of empty "words" between successive whitespace characters. Get rid of this by filtering out empty strings:
let components = str.components(separatedBy: .whitespacesAndNewlines)
let words = components.filter { !$0.isEmpty }
print(words.count) // 17
The above will print 17 because you haven't included , as a separation character, so the string "planners,are" is treated as one word.
You can break that string up as well by adding punctuation characters to the set of separators like so:
let chararacterSet = CharacterSet.whitespacesAndNewlines.union(.punctuationCharacters)
let components = str.components(separatedBy: chararacterSet)
let words = components.filter { !$0.isEmpty }
print(words.count) // 18
Now you'll see a count of 18 like you expect.

NSString.rangeOfString returns unusual result with non-latin characters

I need to get the range of two words in a string, for example:
ยัฟิแก ไฟหก
(this is literally me typing PYABCD WASD) - it's a non-sensical test since I don't speak Thai.
//Find all the ranges of each word
var words: [String] = []
var ranges: [NSRange] = []
//Convert to nsstring first because otherwise you get stuck with Ranges and Strings.
let nstext = backgroundTextField.stringValue as NSString //contains "ยัฟิแก ไฟหก"
words = nstext.componentsSeparatedByString(" ")
var nstextLessWordsWeHaveRangesFor = nstext //if you have two identical words this prevents just getting the first word's range
for word in words
{
let range:NSRange = nstextLessWordsWeHaveRangesFor.rangeOfString(word)
Swift.print(range)
ranges.append(range)
//create a string the same length as word
var fillerString:String = ""
for i in 0..<word.characters.count{
//for var i=0;i<word.characters.count;i += 1{
Swift.print("i: \(i)")
fillerString = fillerString.stringByAppendingString(" ")
}
//remove duplicate words / letters so that we get correct range each time.
if range.length <= nstextLessWordsWeHaveRangesFor.length
{
nstextLessWordsWeHaveRangesFor = nstextLessWordsWeHaveRangesFor.stringByReplacingCharactersInRange(range, withString: fillerString)
}
}
outputs:
(0,6)
(5,4)
Those ranges are overlapping.
This causes problems down the road where I'm trying to use NSLayoutManager.enumerateEnclosingRectsForGlyphRange since the ranges are inconsistent.
How can I get the correct range (or in this specific case, non-overlapping ranges)?
Swift String characters describe "extended grapheme clusters", and NSString
uses UTF-16 code points, therefore the length of a string differs
depending on which representation you use.
For example, the first character "ยั" is actually the combination
of "ย" (U+0E22) with the diacritical mark " ั" (U+0E31).
That counts as one String character, but as two NSString characters.
As a consequence, indices change when you replace the word with
spaces.
The simplest solution is to stick to one, either String or NSString
(if possible). Since you are working with NSString, changing
for i in 0..<word.characters.count {
to
for i in 0..<range.length {
should solve the problem. The creation of the filler string
can be simplified to
//create a string the same length as word
let fillerString = String(count: range.length, repeatedValue: Character(" "))
Removing nstextLessWordsWeHaveRangesFor solves the issue (at the bottom starting with range.length <= nstextLessWordsWeHaveRangesFor.length). The modification of that variable is changing the range and giving unexpected output. Here is the result when the duplicate word removal is removed:
var words: [String] = []
let nstext = "ยัฟิแก ไฟหก" as NSString
words = nstext.componentsSeparatedByString(" ")
for word in words {
let range = nstext.rangeOfString(word)
print(range)
}
Output is: (0,6) and (7,4)

jquery add numbers within one input field

I have found ways to add the numbers of multiple input fields together and output the result. However I am trying to find a way to add numbers within one field, if possible. I basically want it to work as if it was an excel cell and add up numbers using a + in between each one.
So as the user enters =125+11+110 it automatically is adding those numbers to and displaying the total next to the box.
You can split the string:
var expression = "125+11+110";
var operands = expression.split("+");
var sum = 0;
for (var i = 0; i < operands.length; i++) {
sum += parseInt(operands[i]); // use parseFloat if you use decimals as well.
}
But the above example will not know hot to do multiple types of operations in single text box. For example, 100+76-45 will give you incorrect answer.
You can also use eval, but know that it can be harmful if you used it in a wrong way.
var expression = "125+11+110";
var sum = eval(expression);
If you use eval:
do not store the strings user submitted in the database without sanitation.
do not send back the strings user submitted to the browser as JavaScript.
to be safe, just do not even send the user's strings to server at all.
This is the dirty method. It splits the input between the plus signs and adds up the values in the array:
var userinput = "125+11+110";
var userinputarray = userinput.split("+");
var totalamount = 0;
$(userinputarray).each(function(key,value){
totalamount += parseFloat(value);
})
It does not handle subtraction. However you can do a regex match instead:
var userinput = "125+11+110";
var userinputarray = userinput.match(/(\+|\-){0,1}[0-9.]{1,}/g);
var totalamount = 0;
$(userinputarray).each(function(key,value){
totalamount += parseFloat(value);
});
Parsefloat will remove the + symbol, while still using the negative sign.
var data = $('#inputfeildID').text();
var arr = data.split('+');
var total = 0;
for(i=0; i < arr.length ; i ++){
total += arr[i];
}
console.log( total );
When user click enter or submit , first get the value or text in the input field & then split it from + , then add the array elements . you will get the total value of the input box ..
if you want to add those number automatically when user is typing , you have to use jQuery keyup function & when user press + , then add the next number to previous one
You can put a keyup listener on the text box. Then in the code fired by the listener, if "myinput" is the id of your input field:
var exp = document.getElementById('myinput').value;
var result = eval(exp);
"result" will be the value of the expression. You should also really check "exp" to see that it is a valid entry, because the user could put any kind of garbage into the input field, and there could also be security issues.
You should use eval. Like so...
var input = "125+11+110";
var answer = eval(input);
http://www.w3schools.com/jsref/jsref_eval.asp