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);
}
}
Related
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;
I have this bit of code in a class:
public class TicketSummary
{
//get all the development tickets
public List<IncidentSummary> AllDevelopmentTickets { get; set; }
public List<string> TicketNames()
{
List<string> v = new List<string>();
foreach (var developmentTicket in AllDevelopmentTickets)
{
var ticketIds = developmentTicket.id.ToString(CultureInfo.InvariantCulture);
v.Add(ticketIds);
}
return v;
}
}
}
And I am trying to see if my API connection (plus all the code) did it's job and pulls back the tickets and their info, more specifically the ids.
In my main program I have no clue how to check if it did the job. I tried something but it isn't quite right and doesn't return anything ( I know I need a Console.WriteLine)
static void Main(string[] args)
{
Console.ReadLine();
var tickets = new TicketSummary();
tickets.TicketNames();
while ( tickets != null )
{
Console.WriteLine(tickets);
}
}
Any suggestions, please?
Thank you!
You've dropped the returned result: tickets.TicketNames(); returns List<String> that you have to assign and then itterate:
var tickets = new TicketSummary();
var names = tickets.TicketNames(); // <- names, List<String> according to the code
// printing out all the names
foreach(var name in names)
Console.WriteLine(name);
Do you mean you just want to print all the tickets out?
foreach (var ticket in tickets.TicketNames())
{
Console.WriteLine(ticket);
}
You have several problems in your code, that should keep it from even compiling, but aside from that, It seem's what you're really after is rather transforming the data in AllDevelopmentTickets, rather than moving it somewhere. So you could probably do it with a Select call (from LINQ). So, in your main method:
var tickets = new TicketSummary();
// add some tickets to tickets.AllDevelopmentTickets here...
var ticketNames = tickets.AllDevelopmentTickets.Select(ticket => ticket.id.ToString();
// Yes, you should probably use an UI culture in the ToString call.
// I'm just trying to limit my line width =)
Now, ticketNames should be an IEnumerable<string> holding all the ticket ids. To, for example, print them out, you can iterate over them and write to console output:
foreach (var name in ticketNames) {
Console.WriteLine(name);
}
You need to assign / use the return value of the TicketNames() method. This seems a lot of work just to return the string version of the TicketId. This can be reduced
public List<string> TicketNames()
{
return AllDevelopmentTickets
.Select(t => t.id.ToString(CultureInfo.InvariantCulture))
.ToList();
}
var ticketSummary = new TicketSummary();
var ticketNames = ticketSummary.TicketNames();
foreach(var ticketName in ticketNames)
{
Console.WriteLine(ticketName);
}
or Even just:
foreach(var ticketName in AllDevelopmentTickets
.Select(t => t.id.ToString(CultureInfo.InvariantCulture)))
{
Console.WriteLine(ticketName);
}
You're ignoring the returned value.
static void Main(string[] args)
{
Console.ReadLine();
var tickets = new TicketSummary();
var res = tickets.TicketNames();
while ( for r in res )
{
Console.WriteLine(r);
}
}
I have a list that contains 3 items, two of type_1, and one of type_2. I want to return a second list that contains the type and number of that type that exists. When stepping through the breakpoints set at the foreach loop, the IF statement is never true. I assume there is something wrong with my attempt to use Contains() method.
The output should be something like:
type_1 2
type_2 1
Instead, it evaluates as:
type_1 1
type_1 1
type_2 1
Is my use of Contains() not correct?
public List<item_count> QueryGraphListingsNewAccountReport()
List<item> result = new List<items>();
var type_item1 = new item { account_type = "Type_1" };
var type_item2 = new item { account_type = "Type_1" };
var type_item3 = new item { account_type = "Type_2" };
result.Add(type_item1);
result.Add(type_item2);
result.Add(type_item3);
//Create a empty list that will hold the account_type AND a count of how many of that type exists:
List<item_count> result_count = new List<item_count>();
foreach (var item in result)
{
if (result_count.Contains(new item_count { account_type = item.account_type, count = 1 } ) == true)
{
var result_item = result_count.Find(x => x.account_type == item.account_type);
result_item.count += 1;
result_count.Add(result_item);
}
else
{
var result_item = new item_count { account_type = item.account_type, count = 1 };
result_count.Add(result_item);
}
}
return result_count;
}
public class item
{
public string account_type { get; set; }
}
public class item_count
{
public int count {get; set;}
public string account_type { get; set; }
}
I think your problem is that you don't want to use contains at all. You are creating a new object in your contains statement and, obviously, it isn't contained in your list already because you only just created it. The comparison is comparing references, not values.
Why not just use the find statement that you do in the next line instead? If it returns null, then you know there isn't an item already with that type.
So you could do something like this:
var result_item = result_count.Find(x => x.account_type == item.account_type);
if (result_item != null)
{
result_item.count++;
// note here you don't need to add it back to the list!
}
else
{
// create your new result_item here and add it to your list.
}
Note: Find is o(n), so this might not scale well if you have a really large set of types. In that case, you might be better off with Saeed's suggestion of grouping.
You can do:
myList.GroupBy(x=>x.type).Select(x=>new {x.Key, x.Count()});
If you want use for loop, it's better to use linq Count function to achieve this, If you want use Contains you should implement equal operator as the way you used.
I have a list of strings, such as:
{ abc001, abc002, abc003, cdef001, cdef002, cdef004, ghi002, ghi001 }
I want to get all the common unique prefixes; for example, for the above list:
{ abc, cdef, ghi }
How do I do that?
var list = new List<String> {
"abc001", "abc002", "abc003", "cdef001",
"cdef002", "cdef004", "ghi002", "ghi001"
};
var prefixes = list.Select(x = >Regex.Match(x, #"^[^\d]+").Value).Distinct();
It may be a good idea to write a helper class to represent your data. For example:
public class PrefixedNumber
{
private static Regex parser = new Regex(#"^(\p{L}+)(\d+)$");
public PrefixedNumber(string source) // you may want a static Parse method.
{
Match parsed = parser.Match(source); // think about an error here when it doesn't match
Prefix = parsed.Groups[1].Value;
Index = parsed.Groups[2].Value;
}
public string Prefix { get; set; }
public string Index { get; set; }
}
You need to come up with a better name, of course, and better access modifiers.
Now the task is quite easy:
List<string> data = new List<string> { "abc001", "abc002", "abc003", "cdef001",
"cdef002", "cdef004", "ghi002", "ghi001" };
var groups = data.Select(str => new PrefixedNumber(str))
.GroupBy(prefixed => prefixed.Prefix);
The result is all data, parsed, and grouped by the prefix.
You can achieve that using Regular Expression to select the text part, and then use HashSet<string> to add that text part so no duplication added:
using System.Text.RegularExpressions;
//simulate your real list
List<string> myList = new List<string>(new string[] { "abc001", "abc002", "cdef001" });
string pattern = #"^(\D*)\d+$";
// \D* any non digit characters, and \d+ means followed by at least one digit,
// Note if you want also to capture string like "abc" alone without followed by numbers
// then the pattern will be "^(\D*)$"
Regex regex = new Regex(pattern);
HashSet<string> matchesStrings = new HashSet<string>();
foreach (string item in myList)
{
var match = regex.Match(item);
if (match.Groups.Count > 1)
{
matchesString.Add(match.Groups[1].Value);
}
}
result:
abc, cde
Assuming that your prefix is all alpha characters and terminited by the first non-alpha character, you could use the following LINQ expression
List<string> listOfStrings = new List<String>()
{ "abc001d", "abc002", "abc003", "cdef001", "cdef002", "cdef004", "ghi002", "ghi001" };
var prefixes = (from s in listOfStrings
select new string(s.TakeWhile(c => char.IsLetter(c)).ToArray())).Distinct();
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);