Method to check array list containing specific string - c#

I have an ArrayList that import records from a database.
Is there any method to check whether the arrayList contains schname that i want to match to another list which is an api?
List<PrimaryClass> primaryList = new List<PrimaryClass>(e.Result);
PrimaryClass sc = new PrimaryClass();
foreach (string item in str)
{
for (int a = 0; a <= e.Result.Count - 1; a++)
{
string schname = e.Result.ElementAt(a).PrimarySchool;
string tophonour = e.Result.ElementAt(a).TopHonour;
string cca = e.Result.ElementAt(a).Cca;
string topstudent = e.Result.ElementAt(a).TopStudent;
string topaggregate = e.Result.ElementAt(a).TopAggregate;
string topimage = e.Result.ElementAt(a).TopImage;
if (item.Contains(schname))
{
}
}
}
This is what I have come up with so far, kindly correct any errors that I might have committed. Thanks.

How about ArrayList.Contains?

Try this
foreach( string row in arrayList){
if(row.contains(searchString)){
//put your code here.
}
}

Okay, now you've shown that it's actually a List<T>, it should be easy with LINQ:
if (primaryList.Any(x => item.Contains(x.PrimarySchool))
Note that you should really consider using foreach instead of a for loop to iterate over a list, unless you definitely need the index... and if you're dealing with a list, using the indexer is simpler than calling ElementAt.

// check all types
var containsAnyMatch = arrayList.Cast<object>().Any(arg => arg.ToString() == searchText);
// check strings only
var containsStringMatch = arrayList.OfType<string>().Any(arg => arg == searchText);

Related

How to remove first occurence of element in List C# with LINQ?

I have the following list
List<string> listString = new List<string>() { "UserId", "VesselId", "AccountId", "VesselId" };
I would like to use a Linq operator which removes only the first occurrence of VesselId.
you can not change the original collection with LINQ, so the closest thing would be:
var index = listString.IndexOf("VesselId");
if(index>-1)
listString.RemoveAt(index);
EDIT 1:
According to research done by Igor Mesaros, I ended up implementing the logic which resides in the List.Remove method, so an even simpler solution would be:
listString.Remove("VesselId");
If you have a simple list of strings or some other primitive type, then you can just call:
listString.Remove("VesselId");
as mentioned by #Eyal Perry
If you have a huge none primitive list, this is the most efficient
class MyClass
{
string Name {get; set;}
}
var listString = new List<MyClass>() {/* Fill in with Data */};
var match = listString.FirstOrDefault(x => x.Name == "VesselId");
if(match != null)
listString.Remove(match);
If what you are looking to do is get a distinct list then you have an extension method for that listString.Distinct()
If you absolutely MUST use LINQ, you can use it to find the first instance of "VesselId" inside the Remove() method, like so:
listString.Remove((from a in listString
where a == "VesselId"
select a).First());
listString = listString.Union(new List<string>()).ToList();
OR
List<string> CopyString = new List<string>();
CopyString.AddRange(listString);
foreach (var item in CopyString)
{
var index = CopyString.IndexOf(item);
if (index >= 0 && listString.Count(cnt => cnt == item) > 1)
listString.RemoveAt(index);
}

C# - Nested Array/Data structures

Recently, I have been getting into C# (ASP.NET) and moving on from PHP. I want to achieve something like this:
mainArray (
array 1 (
'name' => 'example'
),
array 2 (
'name' => 'example2'
)
);
I know that you can use an Array in C# however, you must indicate the length of the Array before doing so which is where the problem is.
I want to loop through a Database in a Class function which returns an Array of all the columns, ie:
id, username, email.
I have tried:
public Array search_bustype(string match, string forthat)
{
db = new rkdb_07022016Entities2();
var tbl = (from c in db.tblbus_business select c).ToArray();
List<string> List = new List<string>();
int i = 0;
foreach (var toCheck in tbl)
{
if (toCheck.BusType.ToString() == match)
{
if (forthat == "Name")
{
List.Add(toCheck.Name);
}
if (forthat == "Address")
{
}
}
i++;
}
return List.ToArray();
}
But as you can see, I am having to only return the single column because the List is not multidimensional (can't be nested).
What can I use to solve this issue? I have looked at some links:
C# Arrays
StackOverflow post
But these again are an issue for my structure since I don't know how many index's I need in the Array when declaring it - The Database grows everyday.
Thanks in advance.
Try something like this. First, define a class for your business model.
public class Person
{
public string Name {get;set;}
public string Address {get;set;}
}
Then use a generic list instead of a string list.
public Person[] search_bustype(string match, string forthat)
{
var db = new rkdb_07022016Entities2();
List<Person> personList = new List<Person>();
foreach (var toCheck in db.tblbus_business.Where(b => b.BusType.ToString() == match))
{
var model = new Person { Name = toCheck.Name, Address = toCheck.Address };
personList.Add(model);
}
return personList.ToArray();
}
I'm not sure what you are trying to do with the forthat variable.
You can use a list of lists
IList<IList<string>> multiList;

Table of strings in C#

Is there a way of creating a table with each cell containing a string in C# ?
The closest thing I found is multidimensional arrays string[,] names;, but it seems like its length needs to be defined which is a problem to me.
Here is what my code looks like :
string[] namePost;
int[] numbPage;
string post="";
string newPost;
int i=0;
int j=0;
foreach (var line in File.ReadLines(path).Where(line => regex1.Match(line).Success))
{
newPost = regex1.Match(line).Groups[1].Value;
if (String.Compare(newPost, post) == 0)
{
j = j + 1;
}
else
{
namePost[i] = post;
numbPage[i] = j;
post = newPost;
j = 1;
i = i + 1;
}
}
Each instance of the for writes the name of the new "post" in a cell of namePost. In the end, the namePost table stores the name of all the posts that are different from one another.
What is the best way to achieve that ?
If you are simply trying to store the posts, you can use the List class from the System.Collections.Generic namespace:
using System.Collections.Generic;
List<String> namePost = new List<String>();
Then, instead of namePost[i] = post;, use
namePost.Add(post);
DataTable
https://msdn.microsoft.com/en-us/library/system.data.datatable(v=vs.110).aspx
Use this, no need to define length at all.
Useful guide and examples:
http://www.dotnetperls.com/datatable
You can just use a
var table = new List<List<string>>();
This would give you a dynamic 2D table of strings.
This will give you all your unique posts. If you want the result as a list you can just do a
.ToList ()
with the result.
static IEnumerable<string> AllPosts(Regex regex, string filePath)
{
return File.ReadLines (filePath)
.Where (line => regex.Match (line).Success)
.Select (line => regex.Match (line).Groups [1].Value)
.Distinct ();
}

How to get all elements into list or string with Selenium using C#?

I've tried using WebElement (and IWebElement) and string lists, but I keep getting errors. How can I get a list or strings of all the elements text by classname? I have all Selenium references. Do I need some java.util dll?
Should I implement a foreach loop?
IList<IWebElement> all = new IList<IWebElement>();
all = driver.FindElements(By.ClassName("comments")).Text;
Error: Cannot create an instance of the abstract class or interface 'System.Collections.Generic.IList'
Error: 'System.Collections.ObjectModel.ReadOnlyCollection' does not contain a definition for 'Text' and no extension method 'Text' accepting a first argument of type
You can get all of the element text like this:
IList<IWebElement> all = driver.FindElements(By.ClassName("comments"));
String[] allText = new String[all.Count];
int i = 0;
foreach (IWebElement element in all)
{
allText[i++] = element.Text;
}
Although you've accepted an answer, it can be condensed using LINQ:
List<string> elementTexts = driver.FindElements(By.ClassName("comments")).Select(iw => iw.Text);
You can't create an instead of IList<T>, you have to create an instance of class that implements the interface, e.g. List<T>:
IList<IWebElement> all = new List<IWebElement>();
However, you need .Text of each IWebElement, so your list should probably be List<string>:
IList<string> all = new List<string>();
Use foreach to add items into your list:
foreach(var element in driver.FindElements(By.ClassName("comments"));
{
all.Add(element.Text);
}
You can do it this way too, and it parses through the menu list and gets the list text.
IWebElement menuOptions;
menuOptions = _browserInstance.Driver.FindElement(By.XPath(".//*[#id='xxxxxxxxxxxxxxxxxx']/ul[2]/li[3]"));
IList<IWebElement> list = menuOptions.FindElements(By.TagName("li"));
//// get the column headers
char[] character = "\r\n".ToCharArray();
string[] Split = menuOptions.Text.Split(character);
for (int i = 0; i < Split.Length; i++)
{
if (Split[i] != "")
{
_log.LogEntry("INFO", "column Text", true,
Split + " Text matches the expected:" + Split[i]);
}
}
I have used this form
public List<string> GetValidations()
{
IList<IWebElement> elementList = _webDriver.FindElements(By.Id("validationList")); // note the FindElements, plural.
List<string> validations = new List<string>();
foreach (IWebElement element in elementList)
{
validations.Add(element.ToString());
}
return validations;
}

Enumerated int List<GradeRange>

I really have no clue about enumerated list, but after some research I found that this list may help solve my problem. So I have a string in my settings called strGrades, and it is a range of strings that I manually update. The range is 0155-0160, 0271-0388, 0455-0503, 0588-687. What I basically want to do is find the values that are not in this grade list (for example 0161,0389, 0504-0587...)
So I came up with a function that will allow me to get each match in the grade range:
public static List<GradeRange> GetValidGrades()
{
MatchCollection matches= Regex.Matches(Settings.Default.productRange,
Settings.Default.srGradeRange);
List<GradeRange> ranges= new List<GradeRange();
if(matches.Count >0)
{
foreach (Match match in matches)
{
ranges.Add(new GradeRange() 23 {
Start= int.Parse(match.Groups["Start"].Value),
Stop= int.Parse(match.Groups["Stop"].Value)
});
}
}
return ranges;
}
here is the grade range class
public class GrandRange
{
public int Start{get; set;)
public int Stop {get; set; )
}
So the function above caputures my Start and End values, can anyone please help me get this into a list where I can find the values that fall outside of the range values, I just need a starting point. Thanks so much!
You could use a custom extension method that creates .Between along with a Where
var myFilteredList = list.Where(x=>!myValue.Between(x.Start, x.Stop, true));
This isnt the most performant answer, but if you need a list of all the numbers that are not between certain ranges, then you could do something like this:
var missingNumbers = new List<int>();
var minStop = list.OrderBy(x=>x.Stop).Min().Stop;
var maxStart = list.OrderBy(x=>x.Start).Max().Start;
Enumerable.Range(minStop, maxStart).ToList()
.ForEach(x=>
{
if(!x.Between(x.Start, x.Stop, true))
missingNumbers.Add(x);
}
);
Here this should get you started
var strings = "0155-0160, 0271-0388, 0455-0503, 0588-687";
var splitStrings = strings.Split(char.Parse(","));
var grads = new List<GrandRange>();
foreach (var item in splitStrings) {
var splitAgain = item.Split(char.Parse("-"));
var grand = new GrandRange
{
Start = int.Parse(splitAgain[0]),
Stop = int.Parse(splitAgain[1])
};
grads.Add(grand);
}
}

Categories