I basically have criminals with different variables that are added to a report and it looks something like this:
reports.Add(new Report(tbxCriminalSuspicion.Text,
(new Criminal(Ordformatering(tbxName.Text), Ordformatering(tbxSex.Text), int.Parse(tbxAge.Text),
double.Parse(tbxHeight.Text), Ordformatering(tbxHairColor.Text)))));
Then I create another string that I want to use to search between the criminals. You type into a textbox and it is placed into a list by:
string allSearchWords = tbxSearchWords.text;
List<string> splitSearchWords = new List<string>();
allSearchWords = allSearchWords.Replace(" ", "");
splitSearchWords = allSearchWords.Split(',').ToList();
Now I've got a list of words and I'm able to search my criminals via:
splitSearchWords.All((criminal).Contains);
However, in the case of the situation looking as:
Criminal 1: 18 years old, 176 cm
Criminal 2: 34 years old, 180 cm
Both criminals will show up in the Listbox even though only one is 18 years old. In other words, is it possible to search for an exact match using a list as a pattern? Can attach some code.
List<Report> reports = new List<Report>();
List<string> splitSearchWords = new List<string>();
private void btnSearch_Click(object sender, EventArgs e)
{
lbxLista.Items.Clear();
if (string.IsNullOrWhiteSpace(tbxSearchWords.Text))
{
MessageBox.Show("Vänligen fyll i dina sökord innan du söker enligt \"Sökord, sökord, sökord, ...\"",
"Felinmatning", MessageBoxButtons.OK, MessageBoxIcon.Information);
//Just a check so that the searchbox isn't empty!!!!
}
else
{
string allSearchWords = tbxSearchWords.Text;
allSearshWords = allSearshWords.Replace(" ", "");
splitSearchWords = allSearchWords.Split(',').ToList();
for (int i = 0; i < reports.Count; i )
{
if(ContainsSearchWord(reports[i].GetData(), splitSearchWords))
{
lbxLista.Items.Add(reports[i].ToString());
}
}
}
}
public static bool ContainsSearchWord(string stringToTest, List<string> searchedWords)
{
return searchedWords.All((stringToTest).Contains);
}
The Classes, Report and Criminal:
class Report
{
public string GetData()
{
return "" criminal.criminalName " " criminal.criminalSex
" " criminal.criminalAge " "
criminal.criminalHeight " " criminal.criminalHairColor;
}
}
class Criminal
{
private string privatCriminalName;
private string privatCriminalSex;
private int privatCriminalAge;
private double privatCriminalHeight;
private string privatCriminalHairColor;
public Criminal(string mCriminalName, string mCriminalSex,
int mCriminalAge, double mCriminalHeight, string mCriminalHeightColor)
{
this.criminalName = mCriminalName;
this.criminalSex = mCriminalSex;
this.criminalAge = mCriminalAge;
this.criminalHeight = mCriminalHeight;
this.criminalHairColor = mCriminalHeightColor;
}
//Then I have properties to access these from outside the class but removed due to being messy and lengthy in post.
}
Pardon the long post, after 10 hours I'm just lost.
CodePudding user response:
Instead of using a string to test the pattern, you can use an array. This array would contain each of the traits and the crime as separate string
values. This way, you can still use Contains
, but it will individually test the strings, instead of their substrings.
public static bool ContainsSearchWord(string stringToTest, List<string> searchedWords) {
return searchedWords.All((stringToTest.Split(' ')).Contains);
}
You don't even have to create a variable for this, just use Split()
on what you already have.
CodePudding user response:
is it possible to search for an exact match using a list as a pattern?
Taking a bit of a stab in the dark here but if you have these strings:
criminals = new string[] {
"Criminal 1: 18 years old, 176 cm",
"Criminal 2: 34 years old, 180 cm"
}
And the user types this as their search term:
18,old
And you want to make sure the "18" doesn't match 180 in the height of Criminal 2, then you can use a regular expression:
var searchTerms = "18,old".Split(',').Select(s => $@"\b{s}\b").ToArray();
criminals.Where(c => searchTerms.All(st => Regex.IsMatch(c, st)));
This will return only criminal where the string matches all the regular expressions.
Critically, your searchTerms
have become an array like:
new string[] { @"\b18\b", @"\bold\b" };
The \b
means "word boundary" - a zero-width character between a "non word character" like a space, punctuation, end/start of string etc, and the word character you're looking for
Thus \b18\b
will match "he is 18 years old" and "it is 18", but it will not match "it is 180 years old", nor "it is 218 years old" etc
If you want to do it without regex, you could split the criminal strings on space:
var searchTerms = "18,old".Split(',')
criminals.Where(c => {
var words = c.Split();
return searchTerms.All(st => words.Contains(st));
} );
but it's not so sophisticated; it would have old,
in the words
, so my search term above of old
wouldn't find a match.. If you wanted to counter that, you'd have to split on more stuff (punctuation etc) than just space..
Now, about that case sensitivity...