How to convert a String to a searchable Array in dart? - flutter

I have a String like Lion is the king I need to split it in such a way that it returns an array like this :
L
Li
Lio
Lion
""
i
is
""
t
th
the
""
k
ki
kin
king
My CODE :
List<String> splitList = name.split(' ');
List<String> indexList = [];
for (int i = 0; i < splitList.length; i++,) {
for (int j = 0; j < splitList[i].length; j++) {
indexList.add(splitList[i].substring(0, j).toLowerCase());
}
}
return indexList;
Here name is a String.
Result of the above code:
L
Li
Lio
""
i
""
t
th
""
k
ki
kin
Problem with my code :
In my code the last alphabet of every word is missing.
Uses of this:
I am using this for searching purposes, in short I am saving this array in Firestore and create a searching function using array contains: in StreamBuilder

By adding one to the splitList[i].length it should works:
String name = "Lion is the king";
List<String> splitList = name.split(' ');
List<String> indexList = [];
for (int i = 0; i < splitList.length; i++,) {
for (int j = 0; j < splitList[i].length + 1; j++) {
indexList.add(splitList[i].substring(0, j).toLowerCase());
}
}
for (var element in indexList){
print("\n $element");
}
//return indexList

use split to every char
String name = "Lion is the king";
var res = List<String>();
var word = '';
name.split('').forEach((char) {
word = (char.isEmpty) ? '': word + char.toLowerCase();
res.add(word);
});
print(res);
output:
[l, li, lio, lion, , i, is, , t, th, the, , k, ki, kin, king]

The first element of your j loop is using `word.substring(0, 0) or ''.
This is why the result of your method contains an empty string before each word split:
[, l, li, lio, , i, , t, th, , k, ki, kin, king]
Your code with correction:
List<String> indexString(String name) {
List<String> splitList = name.split(' ');
List<String> indexList = [];
for (int i = 0; i < splitList.length; i++,) {
for (int j = 0; j < splitList[i].length; j++) {
indexList.add(splitList[i].substring(0, j + 1).toLowerCase());
}
}
return indexList;
}
But, you'll also have a problem with punctuation.
Input: "Lion, he is the king!"
Output: ["l", "li", "lio", "lion", "lion,", "h", "he", "i", "is", "t", "th", "the", "k", "ki", "kin", "king", "king!"]
RegExp
Maybe you should use Regular Expressions.
void main() {
final name = "Lion, he is the king!";
print(indexString(name));
}
List<String> indexString(String name) {
RegExp regExp = new RegExp(r"(\w+)");
List<String> splitList =
regExp.allMatches(name).map((m) => m.group(0)).toList();
print(splitList);
List<String> indexList = splitList
.map(
(word) => word.split('').fold<List<String>>(
[''],
(acc, curr) => [...acc, '${acc.last}$curr'],
).sublist(1),
)
.expand((i) => i)
.toList();
return indexList;
}
Note: This will also index alphanumeric words.

Related

Split string to keywords in dart

If I have a string that says "This is a good example", is there any way to split it to the following output in dart:
This
This is
This is a
This is a good
This is a good example
I would do it like this:
String text = "This is a good example";
List<String> split = text.split(" ");
for (var i = 0; i < split.length; i++) {
print(split.sublist(0, i + 1).join(" "));
}
String str = "This is a good example";
final split = str.split(" ");
for (int i = 0; i < split.length; i++) {
String result = "";
for (int j = 0; j < i+1; j++) {
result += split[j];
if (j < i) {
result += " ";
}
}
print(result);
}
Result:
This
This is
This is a
This is a good
This is a good example
You could do something like this (easy way):
String myString = "This is a good example";
List<String> output = myString.split(" ");
String prev = "";
output.forEach((element) {
prev += " " + element;
print(prev);
});
Output:
This
This is
This is a
This is a good
This is a good example
If you'd like to simply split a string by word you could do it with the split() function:
String myString = "This is a good example";
List<String> output = myString.split(" ");
output.forEach((element) => print(element));
Output:
This
is
a
good
example

split the string into equal parts flutter

There is a string with random numbers and letters. I need to divide this string into 5 parts. And get List. How to do it? Thanks.
String str = '05b37ffe4973959c4d4f2d5ca0c1435749f8cc66';
Should work:
List<String> list = [
'05b37ffe',
'4973959c',
'4d4f2d5c',
'a0c14357',
'49f8cc66',
];
I know there'a already a working answer but I had already started this so here's a different solution.
String str = '05b37ffe4973959c4d4f2d5ca0c1435749f8cc66';
List<String> list = [];
final divisionIndex = str.length ~/ 5;
for (int i = 0; i < str.length; i++) {
if (i % divisionIndex == 0) {
final tempString = str.substring(i, i + divisionIndex);
list.add(tempString);
}
}
log(list.toString()); // [05b37ffe, 4973959c, 4d4f2d5c, a0c14357, 49f8cc66]
String str = '05b37ffe4973959c4d4f2d5ca0c1435749f8cc66';
int d=1
; try{
d = (str.length/5).toInt();
print(d);
}catch(e){
d=1;
}
List datas=[];
for(int i=0;i<d;i++){
var c=i+1;
try {
datas.add(str.substring(i * d, d*c));
} catch (e) {
print(e);
}
}
print(datas);
}
OR
String str = '05b37ffe4973959c4d4f2d5ca0c1435749f8cc66';
int d = (str.length / 5).toInt();
var data = List.generate(d - 3, (i) => (d * (i + 1)) <= str.length ? str.substring(i * d, d * (i + 1)) : "");
print(data);//[05b37ffe, 4973959c, 4d4f2d5c, a0c14357, 49f8cc66]
If you're into one liners, with dynamic parts.
Make sure to import dart:math for min function.
This is modular, i.e. you can pass whichever number of parts you want (default 5). If you string is 3 char long, and you want 5 parts, then it'll return 3 parts with 1 char in each.
List<String> splitIntoEqualParts(String str, [int parts = 5]) {
int _parts = min(str.length, parts);
int _sublength = (str.length / _parts).ceil();
return Iterable<int>
//Initialize empty list
.generate(_parts)
.toList()
// Apply the access logic
.map((index) => str.substring(_sublength * index, min(_sublength * index + _sublength, str.length)))
.toList();
}
You can then use it such as print(splitIntoEqualParts('05b37ffe4973959c4d4f2d5ca0c1435749f8cc66', 5));
splitWithCount(String string,int splitCount)
{
var array = [];
for(var i =0 ;i<=(string.length-splitCount);i+=splitCount)
{
var start = i;
var temp = string.substring(start,start+splitCount);
array.add(temp);
}
print(array);
}

How to get length of String in flutter and display in firestore array

I need to create an array of information into firestore and I want to achieve this:
I have tried this:
Future uploadData(String name) async {
List<String> splitList = name.split('');
List<String> indexList = [];
for (int i = 0; i < splitList.length; i++){
for (int y = 1 ; y < splitList[i].length + 1; y++) {
indexList.add(splitList[i].substring(0,y).toLowerCase());
}
name = name + name[i];
indexList.add(name);
}
print(indexList);
FirebaseFirestore.instance.collection('Users').doc(_auth.currentUser!.uid).update({
'arrayUser': indexList
});
}
but it crash the application...
Hi have found a way to achieve what I needed.
Hope that can help the community:
Future nameArray(String name) async {
List<String> arrName = [];
String s = name.toLowerCase();
String e = '';
for (int i = 0; i < s.length; i++) {
e = e + s[i];
arrName.add(e);
}
FirebaseFirestore.instance.collection('Users').doc(_auth.currentUser!.uid).update({
'userArray': FieldValue.arrayUnion(arrName)
});

Is there a way to replace multiple keywords in a string and wrapping them with their own keyword?

Say I have a string:
typed = "need replace this ap"
str = "hello I need to replace this asap"
so the end result I want would be this:
newStr = "hello I <bold>need</bold> to <bold>replace</bold> <bold>this</bold> as<bold>ap</bold>"
please don't mind the weird syntax.
I wonder if the order would matter, for example:
typed = "applicable app"
str = "the app is very applicable in many applications"
The end result I wish should be:
newStr = "the <bold>app</bold> is very <bold>applicable</bold> in many <bold>app</bold>lications"
right? is this possible?
Hey,If You can ignore the weird HTML syntax here,
Then I have wrote a solution for you,
Paste this code in dart pad here
removeDuplicates(var typed, var str) {
Map<String, String> m = new Map<String, String>();
var n = typed.length;
String ans = "";
//for storing the "typed" string (word by word) into a map "m" variable for later searching purpose
String temp = "";
int i = 0;
for (i = 0; i < n; i++) {
if (typed[i] == " ") {
m[temp] = temp;
temp = "";
} else {
temp = temp + typed[i];
}
}
//for storing the last word of the string "typed", coz loop will never find a space in last of the string
m[temp] = temp;
// map variable loop for search from map "m" in the "str" string, and matching if the word is present or not
var n2 = str.length;
String temp2 = "";
for (int j = 0; j < n2; j++) {
if (str[j] == " ") {
if (m.containsKey(temp2)) {
} else {
ans = ans + " " + temp2; //storing the "temp2" string into "ans" string, everytime it finds a space and if the string is not already present in the map "m"
}
temp2 = "";
} else {
temp2 = temp2 + str[j];
}
}
//for searching for the last word of the string "str" in map "m", coz loop will never find a space in last of the string,
if (m.containsKey(temp2)) {
} else {
ans = ans + " " + temp2;
}
return ans;
}
void main() {
String typed = "need replace this ap";
var str = "hello I need to replace this asap";
String answer = removeDuplicates(typed, str);
print(answer);
}
Here, I have made a method removeDuplicates() to simplify your work, You just have to pass those string in your method, and then it will return you the desired answer string by removing the duplicates, with a new string.
UPDATED CODE (TO SHOW HTML CODE):
removeDuplicates(var typed, var str) {
Map<String, String> m = new Map<String, String>();
var n = typed.length;
String ans = "";
//for storing the "typed" string (word by word) into a map "m" variable for later searching purpose
String temp = "";
int i = 0;
for (i = 0; i < n; i++) {
if (typed[i] == " ") {
m[temp] = temp;
temp = "";
} else {
temp = temp + typed[i];
}
}
//for storing the last word of the string "typed", coz loop will never find a space in last of the string
m[temp] = temp;
print(m);
// map variable loop for search from map "m" in the "str" string, and matching if the word is present or not
var n2 = str.length;
String temp2 = "";
for (int j = 0; j < n2; j++) {
if (str[j] == " ") {
if (m.containsKey(temp2)) {
temp2 = "<bold>" + temp2 + "</bold> ";
ans = ans + " " + temp2;
} else {
ans = ans +
" " +
temp2; //storing the "temp2" string into "ans" string, everytime it finds a space and if the string is not already present in the map "m"
}
temp2 = "";
} else {
temp2 = temp2 + str[j];
}
}
//for searching for the last word of the string "str" in map "m", coz loop will never find a space in last of the string,
if (m.containsKey(temp2)) {
temp2 = "<bold>" + temp2 + "</bold> ";
temp2 = "";
} else {
ans = ans + " " + temp2;
temp2 = "";
}
return ans;
}
void main() {
var typed = "applicable app";
var str = "the app is very applicable in many applications";
String answer = removeDuplicates(typed, str);
print(answer);
}
UPDATE 2 (ALL THANKS TO PSKINK FOR THE str.replaceAllMapped APPROACH)
replaceWithBoldIfExists(String typed, String str) {
var n = typed.length;
List<String> searchList = new List<String>();
String temp = "";
int i = 0;
for (i = 0; i < n; i++) {
if (typed[i] == " ") {
searchList.add(temp);
temp = "";
} else {
temp = temp + typed[i];
}
}
searchList.add(temp);
String pat = searchList.join('|');
final pattern = RegExp(pat);
final replaced =
str.replaceAllMapped(pattern, (m) => '<bold>${m.group(0)}</bold>');
return replaced;
}
void main() {
var typed = "need replace this ap";
var str = "hello I need to replace this asap";
print(replaceWithBoldIfExists(typed, str));
}

How to match loop a single character with multiple characters in a list and return bigger list dart?

I'm new in flutter and don't know much about dart, and i want ask about my problem.
This my example to graft each character * in listb loop foreach element in lista:
void main() {
var lista = ['1', '2', '3'];
var listb = ['a***' ,'b*','c'];
List<String> filter1 = [];
List<String> filter2 = [];
List<String> filter3 = [];
//
for (var value in listb) {
if (value.contains("*")) {
for (var aa in lista) {
filter1.add( value.replaceFirst('*', '$aa'));
}
}
}
listb.removeWhere((aaa) => aaa.contains('*'));
filter1 = List.from(filter1)..addAll(listb) ;
print('filter1' + '$filter1');
//
for (var value in filter1) {
if (value.contains("*")) {
for (var aa in lista) {
filter2.add( value.replaceFirst('*', '$aa'));
}
}
}
filter1.removeWhere((aaa) => aaa.contains('*'));
filter2 = List.from(filter2)..addAll(filter1) ;
print('filter2' + '$filter2');
//
for (var value in filter2) {
if (value.contains("*")) {
for (var aa in lista) {
filter3.add( value.replaceFirst('*', '$aa'));
}
}
}
filter2.removeWhere((aaa) => aaa.contains('*'));
filter3 = List.from(filter3)..addAll(filter2) ;
print('filter3' + '$filter3');
}
Result out put
filter1[a1**, a2**, a3**, b1, b2, b3, c]
filter2[a11*, a12*, a13*, a21*, a22*, a23*, a31*, a32*, a33*, b1, b2, b3, c]
filter3[a111, a112, a113, a121, a122, a123, a131, a132, a133, a211, a212, a213, a221, a222, a223, a231, a232, a233, a311, a312, a313, a321, a322, a323, a331, a332, a333, b1, b2, b3, c]
And it's very bad if character * to be replace in listb is : "a***********" :))
Is there a shotter way to escape one character need replace is a loop to have result filter3 at output? Thks U!
Darish's answer is a cool application of set theory, though I would argue that it is overkill. You can also achieve this with listB.expand and a recursive generator method:
void main() {
final listA = ['1', '2', '3'];
final listB = ['a***', 'b*', 'c'];
final output = listB.expand((term) => permutationGenerator(term, listA)).toList();
print(output);
}
Iterable<String> permutationGenerator(String input, List<String> replacements) sync* {
if (input.length == 0) {
// If the input is empty, there's nothing to generate
return;
}
if (input.length == 1) {
// If the input is one character, there's no suffix to append
if (input == '*') {
// Input is '*' so yield all the values in replacements
yield* replacements;
} else {
// Input isn't '*' so just yield it alone
yield input;
}
}
// Trim off and cache the first character
String firstChar = input[0];
// Recursively process all possible permutations of the input minus
// the first character
for (var suffix in permutationGenerator(input.substring(1), replacements)) {
if (firstChar == '*') {
// If the first character is '*', replace it with all values in
// replacements and append to it the suffix values calculated
// from the recursive
yield* replacements.map((c) => c + suffix);
} else {
// The first character isn't '*' so just yield it directly
yield firstChar + suffix;
}
}
}
This will output the following list (formatted):
[
a111,
a211,
a311,
a121,
a221,
a321,
a131,
a231,
a331,
a112,
a212,
a312,
a122,
a222,
a322,
a132,
a232,
a332,
a113,
a213,
a313,
a123,
a223,
a323,
a133,
a233,
a333,
b1,
b2,
b3,
c,
]
You can create a general solution by taking Cartesian product of the input strings.
Step 1:
These are the input lists.
var lista = ['1', '2', '3'];
var listb = ['a***' ,'b*','c'];
Split each 'listb' item as shown below
listb.forEach((value) {
///split the string with asterisk symbol
var symbols = value.split('*');
}
Step 2:
For each asterisk symbol, calculate the Cartesian product of the input strings.
Iterable<List<String>> product = cartesian(
List<List<String>>.generate(symbols.length-1, (tempIndex) => lista));
product.forEach((productValue) {
///final output
print("$symbol${productValue.join()}");
});
The complete snippet is here.
void main() {
///strings that we should use for permutation
var lista = ['1', '2', '3'];
///input strings with asterisk that needs to be replaced.
var listb = ['a***', 'b*', 'c'];
listb.forEach((value) {
///split the string with asterisk symbol
var symbols = value.split('*');
for (int i = 0; i < symbols.length; i++) {
var symbol = symbols[i];
if (symbol.isNotEmpty) {
Iterable<List<String>> product = cartesian(
List<List<String>>.generate(symbols.length-1, (tempIndex) => lista));
product.forEach((productValue) {
///final output
print("$symbol${productValue.join()}");
});
}
}
});
}
Iterable<List<T>> cartesian<T>(List<List<T>> inputs) sync* {
if (inputs.isEmpty) {
yield List<T>(0);
return;
}
var indices = List<int>.filled(inputs.length, 0);
int cursor = inputs.length - 1;
outer:
do {
yield [for (int i = 0; i < indices.length; i++) inputs[i][indices[i]]];
do {
int next = indices[cursor] += 1;
if (next < inputs[cursor].length) {
cursor = inputs.length - 1;
break;
}
indices[cursor] = 0;
cursor--;
if (cursor < 0) break outer;
} while (true);
} while (true);
}
The output is
a111
a112
a113
a121
a122
a123
a131
a132
a133
a211
a212
a213
a221
a222
a223
a231
a232
a233
a311
a312
a313
a321
a322
a323
a331
a332
a333
b1
b2
b3
c
You can see a live demo here on DartPad.