Get first few words of a String in dart

6,789

Solution 1

You can use substring method on String like this..

String myString = 'abcdefghijklmnopqrstuvwxyz';
String smallString = myString.substring(0,5); //<-- this string will be abcde

For a specific use case, lets say if you want maximum of 30 characters no matter the number of words in the resulting string, then you could write a function like this..

String smallSentence(String bigSentence){
  if(bigSentence.length > 30){
    return bigSentence.substring(0,30) + '...';
  }
  else{
    return bigSentence;
  }
}

If the requirement is to specifically get the first few words, lets say first 6 words no matter the resulting string's length, then you could write a function like below. We will also need to use indexOf method on String.

String firstFewWords(String bigSentence){
  
  int startIndex = 0, indexOfSpace;
  
  for(int i = 0; i < 6; i++){
    indexOfSpace = bigSentence.indexOf(' ', startIndex);
    if(indexOfSpace == -1){     //-1 is when character is not found
      return bigSentence;
    }
    startIndex = indexOfSpace + 1;
  }
  
  return bigSentence.substring(0, indexOfSpace) + '...';
}

Additional Edit for creating extension -

You can create an extension on String like so

extension PowerString on String {

  String smallSentence() {
    if (this.length > 30) {
      return this.substring(0, 30) + '...';
    } else {
      return this;
    }
  }

  String firstFewWords() {
    int startIndex = 0, indexOfSpace;

    for (int i = 0; i < 6; i++) {
      indexOfSpace = this.indexOf(' ', startIndex);
      if (indexOfSpace == -1) {
        //-1 is when character is not found
        return this;
      }
      startIndex = indexOfSpace + 1;
    }

    return this.substring(0, indexOfSpace) + '...';
  }
}

And use it like this

  String bigText = 'very big text';
  
  print(bigText.smallSentence());
  print(bigText.firstFewWords());

Solution 2

A. Easy Way

To Split String, we are required to have several steps :

  1. Turn it to List

  2. Make New Smaller List

  3. Transform it back to String

Step 1

To turn String into List, we can use this

String bigSentence = 'Lorem Ipsum is'
bigSentence.split(" ")
// ["Lorem", "Ipsum", "is"]

Step 2

Make New Smaller List, for example get first two words,

we use sublist

List<String> splitted = ["Lorem", "Ipsum", "is"]
splitted.sublist(0, 2)
// ["Lorem", "Ipsum"]

Step 3

Transform it back to String

List<String> smaller = ["Lorem", "Ipsum"]
smaller.join(" ")
// "Lorem Ipsum"

Full Functional Code

at the end, we can simplify it to single line of code

String getFirstWords(String sentence, int wordCounts) {
  return sentence.split(" ").sublist(0, wordCounts).join(" ");
}

String bigSentence = '''
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book
''';

main() {
  String result = getFirstWords(bigSentence, 2);
  print(result); // Lorem Ipsum


  String resultDots = getFirstWords(bigSentence, 2) + " ...";
  print(resultDots); // Lorem Ipsum ...


}

Alternatives

Actually, there is another options to achive New Smaller List as suggested in Step 2

Use take
List<String> splitted = ["Lorem", "Ipsum", "is"]
splitted.take(2)
// ["Lorem", "Ipsum"]

B. Hard Way

As suggested by scrimau, the first method above may experience performance hit by its inefficiency splitting maybe thousands of words at first, in order to get several words.

I just learned that Dart has Runes, that may helps us in this case.

To iterate String, firstly we need to transform it into Runes. As stated here, Runes has iterable

We need to have several steps :

1. Validate find Count

  if (findCount < 1) {
    return '';
  }

2. Turn Separator and Sentence into Runes

  Runes spaceRunes = Runes(wordSeparator);
  Runes sentenceRunes = Runes(sentence);

3. Prepare Final String

  String finalString = "";

4. Iterate Runes

The most important part is here, for your case, we need to find Space ' '

So, later if we already found enough space, we just return the Final String

If we have not found enough space, iterate more and append then Final String

Also note here, we use .single, so the word separator must be single character only.

  for (int letter in sentenceRunes) {
    // <------ SPACE Character IS FOUND----->
    if (letter == spaceRunes.single) {
      findCount -= 1;
      if (findCount < 1) {
        return finalString;
      }
    }
    // <------ NON-SPACE Character IS FOUND ----->
    finalString += String.fromCharCode(letter);
  }

Full Functional Code


String bigSentence = '''
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book
''';

String getFirstWordsFast(String sentence, String wordSeparator, int findCount) {
  if (findCount < 1) {
    return '';
  }

  Runes spaceRunes = Runes(wordSeparator);
  Runes sentenceRunes = Runes(sentence);
  String finalString = "";

  for (int letter in sentenceRunes) {
    if (letter == spaceRunes.single) {
      findCount -= 1;
      if (findCount < 1) {
        return finalString;
      }
    }
    finalString += String.fromCharCode(letter);
  }
  return finalString;
}

main() {
  String shorterString = getFirstWordsFast(bigSentence, " ", 5);
  print(shorterString); // Lorem Ipsum is simply dummy
}

Solution 3

void main() {
  String bigSentence =
      "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book";
  
  /// if length of string is greater than 6 words then append dots
  bool appendDots = false;
  
  
  /// this will split string into words
  List<String> tempList = bigSentence.split(" ");

  int start = 0;
  int end = tempList.length;
  /// extract first 6 words
  if (end > 6) {
    end = 6;
    appendDots = true;
  }
  /// sublist of tempList
  final selectedWords = tempList.sublist(start, end);
  /// join the list with space
  String output = selectedWords.join(" ");

   if(appendDots){
     output += "....";
   }
  
  print(output);
}

Edit : Another Solution

Text('Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry\'s standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book',
   maxLines : 1,
   overflow: TextOverflow.ellipsis, 
),

Solution 4

  String sentence = "My single Sentence";
  print(sentence.split(" "));

Try using split(" ") and assign it to a variable and then you can get the first word.

Solution 5

String sampleText = "Lorem ipsum";

sampleText.split(" ").elementAt(0) // Lorem
sampleText.split(" ").elementAt(1) // ipsum
Share:
6,789
Fathah Cr
Author by

Fathah Cr

Cosmosapien from Ziqx Creative Planet

Updated on December 22, 2022

Comments

  • Fathah Cr
    Fathah Cr over 1 year

    How to get first few words (excerpts) from a long String. I have a big story type String and need to display the first 5-10 words on the screen and remaining to be displayed on the next screen. So is there any way to get so. I searched a lot but couldn't resolve the issue. Eg: TO get the first letter we use

    String sentence = "My single Sentence";
    sentence[0] //M
    

    In the same way, I need to get some words. Eg:

    String bigSentence ='''
    Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book
    ''';
    //code to get the excerpt()
    
    //predicted output=> Lorem Ipsum is simply dummy text...
    
  • Fathah Cr
    Fathah Cr almost 4 years
    Thanks, for your answer .substring() method worked for me.
  • Fathah Cr
    Fathah Cr almost 4 years
    Thanks, for your answer .substring() method worked for me.
  • scrimau
    scrimau almost 4 years
    i mean, good that it worked for OP, but technically this is not the correct answer to the question, since expected output for OPs example was "Lorem Ipsum is simply dummy text", not "Lorem".
  • ejabu
    ejabu almost 4 years
    I have same notion. Therefore I just added below new solution that is more relevant to the title
  • Jigar Patel
    Jigar Patel almost 4 years
    @scrimau, yes right. I have now edited the answer to include specific implementation.
  • scrimau
    scrimau almost 4 years
    performance is bad for this for long strings though ... since split continues to split the string even after 2 matches... is there a more performant way?
  • scrimau
    scrimau almost 4 years
    the problem is: the first 30 characters are not necessarily the first 5 words of a string, and OPs question explicitly stated words not characters. OP maybe can work with a character limit or even wanted a function to split a string with a character limit, but the question asks explicitly for a word limit.
  • Jigar Patel
    Jigar Patel almost 4 years
    @scrimau , then again a limit on words won't ensure a limit on characters and vice versa. So it highly depends on the end goal one is trying to achieve. But yes, both cases could be possible. So I have edited the answer to include that case too.
  • Johan Walhout
    Johan Walhout over 3 years
    How could you make a Extension on this function?
  • Jigar Patel
    Jigar Patel over 3 years
    @JohanWalhout I have edited the answer to include how an extension on String can be made for this.
  • Mod
    Mod over 2 years
    Or extra easier way, bigSentence.split(" ").first; & bigSentence.split(" ").last;