Filter strings containing a word in Flutter - flutter

I want to filter a list and remove Strings not containing words starting with a particular string.
Fe.: searching for words starting with "some"
"That is a list of some animals" - should be in the result
"That is a list of something like animals" - should be in the result
"That is a list of handsome animals" - should not be in the result

Might not be the most performant, but unless you're doing this on millions of items, there shouldn't be any problem:
final l = [
'That is a list of some animals',
'That is a list of something like animals',
'That is a list of handsome animals',
];
l.retainWhere((str) => str.split(' ').any((word) => word.startsWith('some')));

The question is already been answered in the simplest form of code. But I am doing it in a layman's way.
final list = [
'That is a list of some animals',
'That is a list of something like animals',
'That is a list of handsome animals',
];
for(var i = 0 ; i < list.length ; i++){
var sentence = list[i].split(' ');
bool found = false;
for(var j = 0 ; j < sentence.length ; j++){
if (sentence[j].startsWith('some')){
found = true;
}
}
if(!found){
list.removeAt(i);
found = false;
}
}
Stored three sentences in the list.
Used a loop to get each sentence.
Split the sentence on the basis of space, to get each word.
Used an array to check each word of the sentence, whether it is starting from some
If any word of the sentence is starting from some, then I removed that sentence from the list

Related

flutter: change strings letters from the letters from list 1 to the letters from list 2

I am trying to change a string letters from the letters from list 1 to the letters from list 2
and I couldn't find a way to do it
this is my 2 lists
List En = ["A","A","B","G","D","R","S","C","T","E","F","K","L","M","N","H","W","Y","Y"];
List Ar = ["ا","أ","ب","ج","د","ر","س","ص","ط","ع","ف","ق","ل","م","ن","ه","و","ى","ي"];
so if the string was "abc" for example it would get the equivalent of the chars A B C from list 1 and then translate them to the same indexes in list 2
I don't know why others are happy with linear searches of lists. To me, that screams for setting up a map one time, and using it repeatedly. Here's what I whipped up in DartPad:
void main() {
var En = ['a', 'b', 'c'];
var Ar = ['1', '2', '3'];
var en2ar = Map<String, String>.fromIterables(En, Ar);
print(en2ar);
var text = 'abcd';
var output =
text.replaceAllMapped(RegExp('.'), (Match m) => en2ar[m.group(0)] ?? '');
print('$text => $output');
}
you can use this function:
setText(){
String input = 'ABC';
List text = input.split('');
String output = '';
List En = ["A","A","B","G","D","R","S","C","T","E","F","K","L","M","N","H","W","Y","Y"];
List Ar = ["ا","أ","ب","ج","د","ر","س","ص","ط","ع","ف","ق","ل","م","ن","ه","و","ى","ي"];
text.forEach((item){
int index = En.indexWhere((element) => element == item);
if(index != -1){
output = output + Ar[index];
}
});
return output;
}
using the indexWhere method you can find the index of a certain char in array a then replace the char with the element at the same index in array b
I would use this flow
cycle the characters of the string you want to repalce
for every character you get the index of the array a
add the item at the same index in the array b to a "result" string
You should now have a string "result" with the characters replaced

Flutter remove whitespace, commas, and brackets from List when going to display as a String

I want to go through my list of strings, and add it to a text element for display, but I want to remove the commas and remove the [] as well as the whitespace, but leave the symbols except the commas and brackets.
So if the List is.
[1,2,#3,*4,+5]
In the text field I want it to show - "12#3*4+5"
I can figure out how to display it, but Im using
Text(myList.tostring().replaceAll('[\\]\\,\\', '')
Is there a way to do this?
You should use the reduce method on your list.
List<String> myList = ["1", "2", "#3", "*4", "+5"];
String finalStr = myList.reduce((value, element) {
return value + element;
});
print(finalStr);
# output: "12#3*4+5"
This method reduces a collection to a single value by iteratively combining elements of the collection using the provided function.
The method takes a function that receives two parameters: one is the current concatenated value, which starts out with the value of the first element of your list, and the second parameter is the next element on your list. So you can do something with those two values, and return it for the next iterations. At last, a single reduced value is returned. In this case, using strings, the code in my answer will concatenate the values. If those were numbers, the result would be a sum of the elements.
If you want to add anything in between elements, simply use the return value. For instance, to separate the elements by comma and whitespace, it should look like return value + " ," + element;.
Unless I'm misunderstanding the question, the most obvious solution would be to use List.join().
List<String> myList = ["1", "2", "#3", "*4", "+5"];
print( myList.join() );
// Result
// 12#3*4+5
You could also specify a separator
print( myList.join(' ') );
// Result
// 1 2 #3 *4 +5

How do I find letters in words that are part of a string and remove them? (List comprehensions with if statements)

I'm trying to remove vowels from a string. Specifically, remove vowels from words that have more than 4 letters.
Here's my thought process:
(1) First, split the string into an array.
(2) Then, loop through the array and identify words that are more than 4 letters.
(3) Third, replace vowels with "".
(4) Lastly, join the array back into a string.
Problem: I don't think the code is looping through the array.
Can anyone find a solution?
def abbreviate_sentence(sent):
split_string = sent.split()
for word in split_string:
if len(word) > 4:
abbrev = word.replace("a", "").replace("e", "").replace("i", "").replace("o", "").replace("u", "")
sentence = " ".join(abbrev)
return sentence
print(abbreviate_sentence("follow the yellow brick road")) # => "fllw the yllw brck road"
I just figured out that the "abbrev = words.replace..." line was incomplete.
I changed it to:
abbrev = [words.replace("a", "").replace("e", "").replace("i", "").replace("o", "").replace("u", "") if len(words) > 4 else words for words in split_string]
I found the part of the solution here: Find and replace string values in list.
It is called a List Comprehension.
I also found List Comprehension with If Statement
The new lines of code look like:
def abbreviate_sentence(sent):
split_string = sent.split()
for words in split_string:
abbrev = [words.replace("a", "").replace("e", "").replace("i", "").replace("o", "").replace("u", "")
if len(words) > 4 else words for words in split_string]
sentence = " ".join(abbrev)
return sentence
print(abbreviate_sentence("follow the yellow brick road")) # => "fllw the yllw brck road"

Display result after validating for loop in Matlab

In the following code, I check to see if the first letter is in the dictionary of words and if the length of the word matches. If it does, return the word. Otherwise, return an error statement.
words = {'apple', 'banana', 'bee', 'salad', 'corn', 'elephant', 'pterodactyl'};
user_letter_input = input('Please enter the first letter of a word: ', 's');
user_num_input = input('Please enter how long you would like the word to be: ');
for i = words
if ((i{1}(1) == user_letter_input) && (length(i{1}) == user_num_input))
result = i;
else
result = 0;
end
end
if (result == 0)
disp('There are no matching words');
else
disp(['Your new word is: ' result]);
end
The comparison returns i being 'apple' if I type a for the first input and 5 for the second input - as it should.
However, at the end when I try to see if (result == 0), it does not display the new word, even though result is not 0.
Could someone help me fix this please?
You are overwriting result each time through your for loop. The only time that result will be 0 after the loop, is if the last word in words matches your criteria.
I would recommend storing the matching words in a separate cell array, or have a boolean array to indicate which words match. In my opinion, using a boolean is better as it takes less memory and doesn't duplicate data.
words = {'apple', 'banana', 'bee', 'salad', 'corn', 'elephant', 'pterodactyl'};
user_letter_input = input('Please enter the first letter of a word: ', 's');
user_num_input = input('Please enter how long you would like the word to be: ');
isMatch = false(size(words));
for k = 1:numel(words)
word = words{k};
isMatch(k) = word(1) == lower(user_letter_input) && ...
numel(word) == user_num_input;
end
if ~any(isMatch)
disp('There are no matching words');
else
disp(['Your matching words are:', sprintf(' %s', words{isMatch})]);
end
Also, as a side note don't use the cell array in the for loop like that. That leads to a lot of confusion. Also avoid using i as a loop variable.
You're overwriting result each time the word in your dictionary doesn't match. The only time this will work is if the last word matches. You need to change both your initialization of result and your loop:
result = 0; %// assume that no words match
for i = words
if (....
result = 1; %// we found a match... record it
end
%// no else! If we get no match, result will already be 0
end
You can use a flag to detect whether a match was found:
breakflag = 0
for i = words
if ((i{1}(1) == user_letter_input) && (length(i{1}) == user_num_input))
breakflag = 1;
break;
end
end
if (breakflag == 0)
disp('There are no matching words');
else
disp(['Your new word is: ' i]);
end

Algorithm to get a list of all words that are anagrams of all substrings (scrabble)?

Eg if input string is helloworld I want the output to be like:
do
he
we
low
hell
hold
roll
well
word
hello
lower
world
...
all the way up to the longest word that is an anagram of a substring of helloworld. Like in Scrabble for example.
The input string can be any length, but rarely more than 16 chars.
I've done a search and come up with structures like a trie, but I am still unsure of how to actually do this.
The structure used to hold your dictionary of valid entries will have a huge impact on efficiency. Organize it as a tree, root being the singular zero letter "word", the empty string. Each child of root is a single first letter of a possible word, children of those being the second letter of a possible word, etc., with each node marked as to whether it actually forms a word or not.
Your tester function will be recursive. It starts with zero letters, finds from the tree of valid entries that "" isn't a word but it does have children, so you call your tester recursively with your start word (of no letters) appended with each available remaining letter from your input string (which is all of them at that point). Check each one-letter entry in tree, if valid make note; if children, re-call tester function appending each of remaining available letters, and so on.
So for example, if your input string is "helloworld", you're going to first call your recursive tester function with "", passing the remaining available letters "helloworld" as a 2nd parameter. Function sees that "" isn't a word, but child "h" does exist. So it calls itself with "h", and "elloworld". Function sees that "h" isn't a word, but child "e" exists. So it calls itself with "he" and "lloworld". Function sees that "e" is marked, so "he" is a word, take note. Further, child "l" exists, so next call is "hel" with "loworld". It will next find "hell", then "hello", then will have to back out and probably next find "hollow", before backing all the way out to the empty string again and then starting with "e" words next.
I couldn't resist my own implementation. It creates a dictionary by sorting all the letters alphabetically, and mapping them to the words that can be created from them. This is an O(n) start-up operation that eliminates the need to find all permutations. You could implement the dictionary as a trie in another language to attain faster speedups.
The "getAnagrams" command is also an O(n) operation which searches each word in the dictionary to see if it is a subset of the search. Doing getAnagrams("radiotelegraphically")" (a 20 letter word) took approximately 1 second on my laptop, and returned 1496 anagrams.
# Using the 38617 word dictionary at
# http://www.cs.umd.edu/class/fall2008/cmsc433/p5/Usr.Dict.Words.txt
# Usage: getAnagrams("helloworld")
def containsLetters(subword, word):
wordlen = len(word)
subwordlen = len(subword)
if subwordlen > wordlen:
return False
word = list(word)
for c in subword:
try:
index = word.index(c)
except ValueError:
return False
word.pop(index)
return True
def getAnagrams(word):
output = []
for key in mydict.iterkeys():
if containsLetters(key, word):
output.extend(mydict[key])
output.sort(key=len)
return output
f = open("dict.txt")
wordlist = f.readlines()
f.close()
mydict = {}
for word in wordlist:
word = word.rstrip()
temp = list(word)
temp.sort()
letters = ''.join(temp)
if letters in mydict:
mydict[letters].append(word)
else:
mydict[letters] = [word]
An example run:
>>> getAnagrams("helloworld")
>>> ['do', 'he', 'we', 're', 'oh', 'or', 'row', 'hew', 'her', 'hoe', 'woo', 'red', 'dew', 'led', 'doe', 'ode', 'low', 'owl', 'rod', 'old', 'how', 'who', 'rho', 'ore', 'roe', 'owe', 'woe', 'hero', 'wood', 'door', 'odor', 'hold', 'well', 'owed', 'dell', 'dole', 'lewd', 'weld', 'doer', 'redo', 'rode', 'howl', 'hole', 'hell', 'drew', 'word', 'roll', 'wore', 'wool','herd', 'held', 'lore', 'role', 'lord', 'doll', 'hood', 'whore', 'rowed', 'wooed', 'whorl', 'world', 'older', 'dowel', 'horde', 'droll', 'drool', 'dwell', 'holed', 'lower', 'hello', 'wooer', 'rodeo', 'whole', 'hollow', 'howler', 'rolled', 'howled', 'holder', 'hollowed']
The data structure you want is called a Directed Acyclic Word Graph (dawg), and it is described by Andrew Appel and Guy Jacobsen in their paper "The World's Fastest Scrabble Program" which unfortunately they have chosen not to make available free online. An ACM membership or a university library will get it for you.
I have implemented this data structure in at least two languages---it is simple, easy to implement, and very, very fast.
A simple-minded approach is to generate all the "substrings" and, for each of them, check whether it's an element of the set of acceptable words. E.g., in Python 2.6:
import itertools
import urllib
def words():
f = urllib.urlopen(
'http://www.cs.umd.edu/class/fall2008/cmsc433/p5/Usr.Dict.Words.txt')
allwords = set(w[:-1] for w in f)
f.close()
return allwords
def substrings(s):
for i in range(2, len(s)+1):
for p in itertools.permutations(s, i):
yield ''.join(p)
def main():
w = words()
print '%d words' % len(w)
ss = set(substrings('weep'))
print '%d substrings' % len(ss)
good = ss & w
print '%d good ones' % len(good)
sgood = sorted(good, key=lambda w:(len(w), w))
for aword in sgood:
print aword
main()
will emit:
38617 words
31 substrings
5 good ones
we
ewe
pew
wee
weep
Of course, as other responses pointed out, organizing your data purposefully can greatly speed-up your runtime -- although the best data organization for a fast anagram finder could well be different... but that will largely depend on the nature of your dictionary of allowed words (a few tens of thousands, like here -- or millions?). Hash-maps and "signatures" (based on sorting the letters in each word) should be considered, as well as tries &c.
What you want is an implementation of a power set.
Also look at Eric Lipparts blog, he blogged about this very thing a little while back
EDIT:
Here is an implementation I wrote of getting the powerset from a given string...
private IEnumerable<string> GetPowerSet(string letters)
{
char[] letterArray = letters.ToCharArray();
for (int i = 0; i < Math.Pow(2.0, letterArray.Length); i++)
{
StringBuilder sb = new StringBuilder();
for (int j = 0; j < letterArray.Length; j++)
{
int pos = Convert.ToInt32(Math.Pow(2.0, j));
if ((pos & i) == pos)
{
sb.Append(letterArray[j]);
}
}
yield return new string(sb.ToString().ToCharArray().OrderBy(c => c).ToArray());
}
}
This function gives me the powersets of chars that make up the passed in string, I then can use these as keys into a dictionary of anagrams...
Dictionary<string,IEnumerable<string>>
I created my dictionary of anagrams like so... (there are probably more efficient ways, but this was simple and plenty quick enough with the scrabble tournament word list)
wordlist = (from s in fileText.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries)
let k = new string(s.ToCharArray().OrderBy(c => c).ToArray())
group s by k).ToDictionary(o => o.Key, sl => sl.Select(a => a));
Like Tim J, Eric Lippert's blog posts where the first thing to come to my mind. I wanted to add that he wrote a follow-up about ways to improve the performance of his first attempt.
A nasality talisman for the sultana analyst
Santalic tailfans, part two
I believe the Ruby code in the answers to this question will also solve your problem.
I've been playing a lot of Wordfeud on my phone recently and was curious if I could come up with some code to give me a list of possible words. The following code takes your availble source letters (* for a wildcards) and an array with a master list of allowable words (TWL, SOWPODS, etc) and generates a list of matches. It does this by trying to build each word in the master list from your source letters.
I found this topic after writing my code, and it's definitely not as efficient as John Pirie's method or the DAWG algorithm, but it's still pretty quick.
public IList<string> Matches(string sourceLetters, string [] wordList)
{
sourceLetters = sourceLetters.ToUpper();
IList<string> matches = new List<string>();
foreach (string word in wordList)
{
if (WordCanBeBuiltFromSourceLetters(word, sourceLetters))
matches.Add(word);
}
return matches;
}
public bool WordCanBeBuiltFromSourceLetters(string targetWord, string sourceLetters)
{
string builtWord = "";
foreach (char letter in targetWord)
{
int pos = sourceLetters.IndexOf(letter);
if (pos >= 0)
{
builtWord += letter;
sourceLetters = sourceLetters.Remove(pos, 1);
continue;
}
// check for wildcard
pos = sourceLetters.IndexOf("*");
if (pos >= 0)
{
builtWord += letter;
sourceLetters = sourceLetters.Remove(pos, 1);
}
}
return string.Equals(builtWord, targetWord);
}