Use enumerations extension methods to shorten code - c#

I want to checkmark some listview items from a given array. How could the code below be shortend with enumeration extension methods.
foreach (Team SelectedTeam in value.Teams)
{
foreach (ListViewItem LVItem in TeamLstVw.Items)
{
Team Team = (Team)LVItem.Tag;
if (SelectedTeam.Equals(Team))
LVItem.Selected = true;
}
}

You could eradicate the outer foreach loop, by using Linq methods inside the inner foreach loop. In this case, you could just check if the current LVItem.Tag is contained inside value.Teams
foreach (ListViewItem LVItem in TeamLstVw.Items)
{
var Team = (Team)LVItem.Tag;
//I'd personally compare an identifier here. Like an Id property
//.Any(x => x.Id == Team.Id)
//Or use .Contains(): value.Teams.Contains(Team)
if(value.Teams.Any(x => x == Team)) {
LVItem.Selected = true;
}
}

Related

Use Foreach loop in MVC

How can I process the foreach loop in MVC. In the bellow controller I am calling a method called SendSimpleMessage() which sends an email to its parameter input but on my controller I am unable to use foreach properly.
[HttpPost]
public ActionResult EmailCampaignProcess(FormCollection collection)
{
//var userType = Request["userType"];
//var emailContent = Request["emailContent"];
//SendSimpleMessage();
//ViewBag.Message = "Hello " + Request["userType"];
var Emails = db.Users.Where(d => d.Subscriptions.Any(x => x.Status == true)).Select(u => u.Email).ToArray();
foreach (Emails as Email) {
SendSimpleMessage(Email);
}
}
Your code is wrong, a foreach loop should look like
foreach (var currentEmail in Emails) { //where var can be your Class maybe Email
SendSimpleMessage(currentEmail);
}
Generally a foreach looks like:
foreach(T objectName in YourCollection){
//T is your class
//objectName is the way you access the object within your loop
//in references the list
//YourCollection is IEnumerable<T>
}
Defintion of ForEach Statement
The for each statement is used to iterate through a collection. You can modify elements in a collection, but you cannot add or delete elements.The statements are executed for each element in the array or collection. After the iteration has been completed for all the elements in the collection, control is transferred to the statement that follows the for each block
Syntax:
for each (type identifier in expression)
{
statements
}
Parameters type
The type of identifier.
identifier
The iteration variable that represents the collection element. When identifier is a Tracking Reference Operator, you can modify the element.
expression
An array expression or collection. The collection element must be such that the compiler can convert it to the identifier type.
statements
One or more statements to be executed.
Simple Example:
string[] countries = { "india", "US", "UK" };
foreach (string value in countries )
{
Console.WriteLine(value);
}
In the same way your code will change like below:
[HttpPost]
public ActionResult EmailCampaignProcess(FormCollection collection)
{
//var userType = Request["userType"];
//var emailContent = Request["emailContent"];
//SendSimpleMessage();
//ViewBag.Message = "Hello " + Request["userType"];
var Emails = db.Users.Where(d => d.Subscriptions.Any(x => x.Status == true)).Select(u => u.Email).ToArray();
foreach (string SingleEmail in Emails) {
SendSimpleMessage(SingleEmail);
}
// Or if you are not sure about the outcome type you can use the var keyword like below
foreach (var SingleEmail in Emails) {
SendSimpleMessage(SingleEmail);
}
}
Hope the above information was helpful

in C# I want to compare two Lists

I have three lists
List1 < Labels > lbl and List2 < Strings > value and List3 < Strings > result
and I wanna compare both using foreach like
if (label1.text == value ) { // value is the 2nd list name
Label_Result.text = Result // in third List
Label1.font= new font("Tahoma",18);
ListBox1.items.add(Label.text);
}
Edit ,,
I think what I need is three Lists
Three basic examples. The first uses a simple nested foreach:
foreach(var item1 in list1)
foreach(var item2 in list2)
if(item1.text == item2)
{
//Do your thing
{
You could reduce nesting by using LINQ. Note that you could make this considerably fancier in LINQ (you can join lists), but I've chosen a simpelr example to show you the basic idea.
foreach(var item1 in list1)
{
var matchesInList2 = list2.Where(item2 => item1.text == item2);
foreach(var match in matchesInList2)
{
//Do your thing
}
}
There is a simpler way to approach it:
var matches = list1.Where(item1 => list2.Contains(item1.text));
foreach(var item1 in matches)
{
//Do your thing, e.g.:
//var theTextValue = item1.text;
}
To explain this simpler approach: we immediately filter list1, and only keep the elements whose .text value exists in list2.
After that, it is simply a matter of looping over the found matches, you don't need to filter anymore.
i think the best way is:
foreach(var list1item in lbl) //List1 item
{
foreach(var list2item in value) //List2 item
{
if(list1item == list2item)
{
//Do something
}
}
}

Is there another way to get a property of a foreach loop item?

I have noticed that a lot of times I need to do something like this
foreach (SomeObject item in listOfItems)
{
string itemName = item.Name;
...
}
But I would much prefer if there was a way to do something like this:
foreach (string item.Name in listOfItems)
{
...
}
Is this possible in C#?
You can use LINQ:
foreach (string name in listOfItems.Select(item => item.Name))
{
// ...
}

How to count itens in a list using foreach and one condition?

I have an 'foreach';
foreach (var item in Model.LstUnidadesGerenciais)
{
var count = Model.LstUnidadesGerenciais.Count;
}
I need to get count with one condition like this:
foreach (var item in Model.LstUnidadesGerenciais)
{
if (item.Level == 1)
{
var count = Model.LstUnidadesGerenciaisWITHCONDITION.Count;
}
}
I think this is simple, but I'm very begginer in C#
Thank you!
Using Linq
var cnt = Model.LstUnidadesGerenciais.Count(x=>x.Level==1);
You can use LINQ Where to select items matching criteria (Level == 1):
var count = Model.LstUnidadesGerenciais.Where(i => i.Level == 1).Count();
Use Count method of LINQ -
var count = Model.LstUnidadesGerenciais.Count(i => i.Level == 1);
In the first example, you don't need the foreach loop. You can tell, because you never use the item, you use the collection instead. I think you need to understand what foreach does here:
foreach (var item in Model.LstUnidadesGerenciais)
{
var count = Model.LstUnidadesGerenciais.Count;
}
foreach will iterate over Model.LstUnidadesGerenciais. This means that for every item in Model.LstUnidadesGerenciais, the code inside the curly brackets is executed, with var item containing the current item of the collection. See MSDN for detailed information
As for the second example: You need a variable that contains a number. In the foreach loop you can increment the variable like:
int count = 0;
foreach (var item in Model.LstUnidadesGerenciais)
{
if (item.Level == 1)
{
count++;
}
}

Performing a boolean AND string search on sub-collections of a collection (non-LINQ)

I hope the title makes sense.
I have a set of items that I want to search and select a subset of, based on a set of keywords that must all appear at least once in any of the SubItems of the Items. I believe this could easily be achieved using LINQ, but I'm using .NET 2.0 for this project.
The code below should achieve pretty much what I want to do, assuming AllBitsAreSet is implemented, but I'm wondering if I'm missing an alternative, simpler way of doing this?
Since there doesn't appear to be a good way of checking if all the bits in a BitArray are set, besides looping through them all (please tell me if there is!), I'm wondering about "nicer" alternatives. Not necessarily more CPU efficient, because I doubt the below code will be too slow for the data sets I'm working with, but ones with less code.
public List<Item> Search(Item[] items, List<string> keywords)
{
List<Item> results = new List<Item>();
BitArray flags = new BitArray(keywords.Count);
foreach (Item item in items)
{
flags.SetAll(false);
foreach (SubItem subItem in item.SubItems)
{
for (int i = 0; i < keywords.Count; i++)
{
if (subItem.StringValue.IndexOf(keywords[i]) >= 0)
flags[i] = true;
}
}
if (AllBitsAreSet(flags)) results.Add(item);
}
return results;
}
You can use LINQ Bridge to get LINQ support on .NET 2.0 and use the following LINQ query.
items.Where(i =>
keywords.All(k =>
i.SubItems.Any(s =>
s.StringValue.Contains(k))));
You can avoid using the bit set if you swap the two inner loops - the performance impact depends on thenumber of sub items vs the number of keywords.
foreach (Item item in items)
{
Boolean found = false;
foreach (String keyword in keywords)
{
found = false;
foreach (SubItem subItem in item.SubItems)
{
if (subItem.StringValue.Contains(keyword))
{
found = true;
break;
}
}
if (!found)
{
break;
}
}
if (found)
{
result.Add(item);
}
}
I would write it as follows. Of course this is very similar to Daniel's solution, but I believe it is better.
public List<Item> Search(Item[] items, List<string> keywords)
{
List<Item> results = new List<Item>();
foreach (Item item in items)
if(ContainsAllKeywords(item, keywords))
results.Add(item);
return results;
}
bool ContainsAllKeywords(Item item, List<string> keywords)
{
foreach (string keyword in keywords)
if (!ContainsKey(item.SubItems, keyword))
return false;
return true;
}
bool ContainsKey(IEnumerable<SubItem> subItems, string key)
{
foreach (SubItem subItem in subItems)
if (subItem.StringValue.Contains(key))
return true;
return false;
}
edit: changed == to .Contains() as per comment

Categories

Resources