c# arraylist searching confusion - c#

I am having problems searching through my Arraylist. The array list stores various information about a number of teams such as the image path to their logo and the team name etc. It is being filled from a separate datafile using a StreamReader
I would like the user to input something in a Textbox from a windows form such as the team name and then consequently the program will then search my arraylist for said string and open another form where the information of the searched team will be loaded up on screen using the Form.Load procedure
To put it simply.
private void btn_Search_Click(object sender, EventArgs e)
{
//what code do I write here?
}
I understand that I might be a little to deep here for my current knowledge of coding so help would be appreciated.
EDIT: unfortunately it must be in an arraylist, sorry for the inconvenience.

If you can use LINQ:
string nameToMatch = "Tigers"; //can you tell who's from Michigan?
List<Team> teams = new ArrayList<Team>();
//fill team data here
Team selected = teams.FirstOrDefault(t => t.TeamName.Equals(nameToMatch, StringComparison.OrdinalIgnoreCase));
Something like this should work. (This will match the text exactly but allow the search to be case insensitive. You can read about other options here.)
If you want to match a list of all "partial matches", you can do this instead:
List<Team> matchedTeams = teams.Select(t => t.TeamName.Contains(nameToMatch));
Read here for an extension overload of Contains that takes a StringComparison enum value.

If you're unfamiliar with LINQ like I am you could use a foreach loop. Something like this:
String nameToMatch = textBox1.text; //read from the text box
foreach (Object obj in Teams)
{
MyTeam team = (MyTeam)obj; //MyTeam is an object you could write that would store team information.
if (team.TeamName.ToUpper() == nameToMatch.ToUpper()) //case insensitive search.
{
FormTeam frmTeam = new FormTeam(team); //windows form that displays team info.
frmTeam.Visible = true;
break; //if team names are unique then stop searching.
}
}
Worst case senario is pretty bad, but for me, at least, it's easier to get my head around than LINQ. Good Luck, hope that helps.

You can use some codes like this to fill your arraylist:
// ArrayList class object
ArrayList arrlist = new ArrayList();
// add items to arrlist collection using Add method
arrlist.Add("item 1");
arrlist.Add("item 2");
arrlist.Add("item 3");
arrlist.Add("item 4");
arrlist.Add("item 5");
and use some codes like this to search in your arraylist
string teamName= this.txtTeamName.Text;
// for loop to get items stored at each index of arrlist collection
for (int i = 0; i < arrlist.Count; i++)
{
if(arrlist[i].toString()==teamName)
// open a new form for show the found team details
}
it is a good practice to change the cunstractor of your "Team Details" form to get a "team name"
frmTeamDetails(team myteam)
then use this code in the above FOR statement:
frmTeamDetals frm=new frmTeamDetals(teamName);
frm.ShowDialog();

Related

C# Comparing if two lists have the same order of items (alphabetical)

I'm facing a huge problem with comparing two lists. I just made copy of my first list and I tried to sort it. The problem is, I want to compare my original list and sorted one to see if they have same alphabetical order. I hope I provided enough information for my problem.
Thanks in advance
public void VerifyDataPrijave(string username)
{
List<string> listaTekstova = new List<string>(); //initializing new, empty List
var kartice = Repo.Kartice.CreateAdapter<Unknown>(false).Find(".//div[class='_63fz removableItem _95l5']");
foreach (var kartica in kartice) {
var slika = kartica.Find(".//tag[tagname='img']")[0];
var ime = slika.Find("following-sibling::div")[0];
string text = ime.GetAttributeValue("InnerText").ToString(); //loop through profile cards and getting Names as InnerText in variable text
listaTekstova.Add(text); //adding those "texts" I just found to an empty list initialized before
List<string> novaListaTekstova = new List<string>(listaTekstova); //clone (copy) of the very first one list
novaListaTekstova.Sort(); //sorting that list alphabetically (I suppose, not sure)
}
}
You can use SequenceEqual to compare to IEnumerables. In your case you can do something like this once all sorting has been done:
var isEqual = novaListaTekstova.SequenceEqual(listaTekstova);

Selenium C# Find Element with class and text

im very new to testing and have no training in automated tests so please bare with me if i say stupid things but ill try the best i can.
Bascially i am trying to assert that a specific employee in the employee list has the status of 'leaver'.
This is what i have tried (and other variations with the different classes)
Assert.Equal("image-tile__badge background-color--status-leaver ng-star-inserted", Driver.FindElement(By.XPath("//*[contains(#class,'image-tile__content-header') and contains(text(),'End Date, Contract') and contains(#class, 'image-tile__badge')]")).GetAttribute("Class"));
Assert.Equal("image-tile__badge background-color--status-leaver ng-star-inserted", Driver.FindElement(By.XPath("//*[contains(#class,'image-tile__content-header') and contains(text(),'End Date, Contract')]")).FindElement(By.XPath("//*[contains(#class, 'image-tile__badge')]")).GetAttribute("Class"));
The last one finds the element when the status is 'new', but when i change the employee status to 'leaver', it still returns as 'new' so possibly looking at another employee with a 'new' status.
Hopefully this is enough info, let me know if more is needed (this is my first ever post!)
HTML code in image below
[HTML code on Chrome]
[1]: https://i.stack.imgur.com/kUxkf.png
Summary: im trying to assert that the Employee "End Date, Contract" has the status of leaver (aka the leaver class "image-tile__badge background-color--status-leaver ng-star-inserted")
Thanks everyone for their help!
One of my devs managed to take #noldors example and modify it a bit so heres what ended up working for me:
var newElmList1 = Driver.FindElements(By.CssSelector("div.background-color--status-leaver")).ToList();
List<string> newNames1 = new List<string>();
foreach (var newElm in newElmList1)
{
var newName1 = newElm.FindElement(By.XPath(".."))
.FindElement(By.CssSelector("div.image-tile__content-header")).Text;
newNames.Add(newName1);
}
if (!newNames.Contains("End Date, Contract"))
{
throw new Exception("Exception Error on leaver Person");
}
As per your screenshot i fill it's better if you try using Xpath
var elmList = Driver.FindElements(By.Xpath("//div[contains(text(),'leaver')]")).ToList();
i hope it will help you
Thank You.
According to your screenshot, you can find all elements with 'Leaver' specific class with this;
var leaverElmList = Driver.FindElements(By.CssSelector("div.background-color--status-leaver")).ToList();
List<string> leaverNames = new List<string>();
foreach (var leaverElm in leaverElmList) {
var leaverName = leaverElm.FindElement(By.XPath(".."))
.FindElement(By.CssSelector("div.image-tile__content-header"));
.Text()
leaverNames.Add(leaverName);
}
Enddate, Contract which is not related to the div that contains Leaver. It's direct parent is the image-tile div

Irrelevant search results with lucene.net

I have been developing a search engine for a business directory application using Lucene.net. However when i search for Sports shop it returns the result of other shops including the sports shops because the key word shop matches with that. So how can i prioritize that it should return the results which is matches with the keyword sport
If anyone have solution for this please share here. Any helpful example or links will be appreciated.
I would very much appreciate it if you could paste some code to give you a better example.
However, from reading your question I think that what you need is a phrase query to give Sports Shop a higher boost.
My implementation of this query is this:
public List QueryToPhraseQuery(string pQuery) {
QueryParsers.Classic.MultiFieldQueryParser oPhraseParser = new QueryParsers.Classic.MultiFieldQueryParser(Version, FieldArray, Analyzer, BoostDictionary);
List<PhraseQuery> lstPhraseQuery = new List<PhraseQuery>();
HashSet<Term> lstTerms = new HashSet<Term>();
oPhraseParser.Parse(pQuery).ExtractTerms(lstTerms);
foreach (var group in lstTerms.GroupBy(x => x.Field))
{
PhraseQuery oPhraseQuery = new PhraseQuery() { Boost = 10, Slop = 3 };
foreach (var oTerm in group.ToList())
{
oPhraseQuery.Add(oTerm);
if (oTerm.Field == Field.ImportantField)
oPhraseQuery.Boost = 30;
}
lstPhraseQuery.Add(oPhraseQuery);
}
return lstPhraseQuery;
}
This would search for thing like this in your index which will match exactly and will return better results with more relevance
attributedescriptions:"something something"~3^10.0 attributemajor:"something something"~3^30.0 description:"something something"~3^10.0 edescription:"something something"~3^10.0
If you want me to give you an example using your code, just past eit and I can modify it to better fit your exam

Find within large list using Contains within Linq

I have two large excel files. I am able to get the rows of these excel files into a list using linqtoexcel. The issue is that I need to use a string from one object within the first list to find if it is part of or contained inside another string within an object of the second list. I was trying the following but the process is taking to long as each list is over 70,000 items.
I have tried using an Any statement but have not be able to pull results. If you have any ideas please share.
List<ExcelOne> exOne = new List<ExcelOne>();
List<ExcelTwo> exTwo = new List<ExcelTwo>();
I am able to build the first list and second list and can verify there are objects in the list. Here was my thought of how I would work through the lists to find matching. Note that once I have found the matching I want to create a new class and add it to a new list.
List<NewFormRow> rows = new List<NewFormRow>();
foreach (var item in exOne)
{
//I am going through each item in list one
foreach (var thing in exTwo)
{
//I now want to check if exTwo.importantRow has or
//contains any part of the string from item.id
if (thing.importantRow.Contains(item.id))
{
NewFormRow adding = new NewFormRow()
{
Idfound = item.id,
ImportantRow = thing.importantRow
};
rows.Add(adding);
Console.WriteLine("added one");
}
}
If you know a quicker way around this please share. Thank you.
It's hard to improve this substring approach. The question is if you have to do it here. Can't you do it where you have filled the lists? Then you don't need this additional step.
However, maybe you find this LINQ query more readable:
List<NewFormRow> rows = exOne
.SelectMany(x => exTwo
.Where(x2 => x2.importantRow.Contains(x.id))
.Select(x2 => new NewFormRow
{
Idfound = x.id,
ImportantRow = x2.importantRow
}))
.ToList();

Splitting a string by a string and inserting into a list C#

So I'm using C# and Visual Studio. I am reading a file of students and their information. The number of students is variable, but I want to grab their information. At the moment I just want to segment the student's information based off of the string "Student ID" because each student's section starts with Student ID. I'm using ReadAllText and setting it equal to a string and then feeding that string to my function splittingStrings. The file will look like this:
student ID 1
//bunch of info
student ID 2
//bunch of info
student ID 3
//bunch of info
.
.
.
I'm wanting to split each segment into a list since the number of students will be unknown, and the information for each student will vary. So I looked into both Regular string split and Regex string splitting. For regular strings I tried this.
public static List<string> StartParse = new List<string>();
public static void splittingStrings(string v)
{
string[] DiagDelimiters = new string[] {"Student ID "};
StartParse.Add(v.Split(DiagDelimiters, StringSplitOptions.None);
}
And this is what I tried with Regex:
StartParse.Add(Regex.Split("Student ID ");
I haven't used Lists before, but from what I've read they are dynamic and easy to use. My only trouble I'm getting is that all examples I see with split are in combination with an array so syntactically I'm not sure how to do a split on a string and insert it into a list. For output my goal is to have the student segments divided so that if I need to I can call a particular segment later.
Let me verify that I'm after that batch of information not the ID's alone. A lot of the questions seem to be focused on that so I felt I needed to verify that.
To those suggesting other storage bodies:
example of what list will hold:
position 0 will hold [<id> //bunch of info]
position 1 will hold [<anotherID> //bunch of info]
.
.
.
So I'm just using the List to do multiple operations on for information that I need. The information will be FAR more manageable if I can segment them into the list as shown above. I'm aware of dictionaries, but I have to store this information either in sql tables or inside text files depending on the contents of the segments. An example would be if one segment was really funky then I would send an error report that one student's information is bad. Otherwise insert neccessary information into sql table. But I'm having to work with multiple things from the segments so I felt the List was the best way to go since I'll have to also go back and forth in the segment to cross check bits of information with earlier things in that segment I found.
There is no need to use RegEx here and I would recommend against it. Simply splitting on white space will do the trick. Lets pretend you have a list which contains each of those lines (student ID 1, student ID 2, ect) you can get a list of the id's very simply like so;
List<string> ids = students.Select(x => x.Split(' ')[2]).ToList();
The statement above essentially says, for each string in students split the string and return the third token (index 2 because it's 0 indexed). I then call ToList because Select by default returns an IEnumerable<T> but I wouldn't worry about those details just yet. If you don't have a list with each of the lines you showed the idea stays much the same, only you would add the items to you ids list one by one as you split the string. For an given string in the form of student id x I would get x on it's own with myString.Split(' ')[2] that is the basis of the expression I pass into Select.
Based on the OP's comment here is a way to get all of the data without the Student Id part of each batch.
string[] batches = input.Split(new string[] { "student id " } StringSplitOptions.RemoveEmptyEntries);
If you really need a list then you can just call ToList() and change type of batches to List<string> but that would probably just be a waste of CPU cycles.
Here's some pseudo-code, and what i'd do:
List<Integer> ids;
void ParseStudentId(string str) {
var spl = str.split(" ");
ids.add(Integer.parseInt(spl[spl.length-1])); // this will fetch "1" from "Student Id 1"
}
void main() {
ParseStudentId("Student Id 1");
ParseStudentId("Student Id 2");
ParseStudentId("Student Id 3");
foreach ( int id in ids )
Console.WriteLin(id); // will result in:
// 1
// 2
// 3
}
forgive me. i'm a java programmer, so i'm mixing Pascal with camel casing :)
Try this one:
StartParse = new List<string>(Regex.Split(v, #"(?<!^)(?=student ID \d+)"));
(?<!^)(?=student ID \d+) which means Splitting the string at the point student ID but its not at the beginning of the string.
Check this code
public List<string> GetStudents(string filename)
{
List<string> students = new List<string>();
StringBuilder builder = new StringBuilder();
using (StreamReader reader = new StreamReader(filename)){
string line = "";
while (!reader.EndOfStream)
{
line = reader.ReadLine();
if (line.StartsWith("student ID") && builder.Length > 0)
{
students.Add(builder.ToString());
builder.Clear();
builder.Append(line);
continue;
}
builder.Append(line);
}
if (builder.Length > 0)
students.Add(builder.ToString());
}
return students;
}

Categories

Resources