Check if collection is empty or not - c#

public ActionResult Create(FormCollection collection, FormCollection formValue)
{
try
{
Project project = new Project();
TryUpdateModel(project, _updateableFields);
var devices = collection["devices"];
string[] arr1 = ((string)devices).Split(',');
int[] arr2 = Array.ConvertAll(arr1, s => int.Parse(s));
project.User = SessionVariables.AuthenticatedUser;
var time = formValue["Date"];
project.Date = time;
project.SaveAndFlush();
foreach (int i in arr2)
{
Device d = Device.Find(i);
d.Projects.Add(project);
d.SaveAndFlush();
}
return RedirectToAction("Index");
}
catch (Exception e)
{
return View(e);
}
}
I want to wrap the foreach in a if statement which checks if
var devices = collection["devices"];
is empty or not. If its empty the for each should not be executed. For the record, collection["devices"] is a collection of checkbox values from a form.

You can use the Count field to check if the collection is empty or not
so you will end up with something like this :
if(devices.Count > 0)
{
//foreach loop
}

You can use the method Any to know if a collection as any element.
if (devices.Any())
{
//devices is not empty
}

You do not need to check if the collection is empty, if it is empty the code inside the ForEach will not be executed, see my example below.
using System;
using System.Collections.Generic;
namespace Test
{
class Program
{
static void Main(string[] args)
{
List<string> emptyList = new List<string>();
foreach (string item in emptyList)
{
Console.WriteLine("This will not be printed");
}
List<string> list = new List<string>();
list.Add("item 1");
list.Add("item 2");
foreach (string item in list)
{
Console.WriteLine(item);
}
Console.ReadLine();
}
}
}

Your code, as it stands, won't work, as you say that collection["devices"] is a collection of checkbox values, and yet you're casting it to a string. Do you mean collection is the checkbox values? What is the exact type of collection?
Any object that implements ICollection or ICollection<T> can be checked whether it's empty or not by checking if the Count property is greater than zero.

How about checking the array length
if (arr2.length > 0)
{
foreach (int i in arr2)
{
Device d = Device.Find(i);
d.Projects.Add(project);
d.SaveAndFlush();
}
}

This worked for me in Dot Net Core but only for IEnumerable of Models not Entities
(I got a bit of help from AutoMapper)
Cast it as a List then check the Capacity
IEnumerable<vwPOD_Master> podMasters = _podRepository.GetNewPods(PartNumber);
IEnumerable<NewPODsDTO> podList = Mapper.Map<IEnumerable<NewPODsDTO>>(podMasters);
if (((List<NewPODsDTO>)podList).Capacity == 0) {
return NotFound();
}

Related

Check if List<string> exists

This is my code
List<string> list = new List<string>() { "bfd", "jy", "aaaaa", "ndnk", "ntfn", "gfm", "gfm", "mhgd5h", "srsr", "ntr", "mtmyt", "dmy", "mmy6", "ngn9d", "y6m1", "d8dm", "bbbbb", "tym", "dmj", "trsh", "tsr"};
List<string> test = new List<string>() {"aaaaa","bbbbb","ccccc","ddddd","eeeee","fffff","ggggg" };
foreach (var a in list)
{
foreach (var i in test)
{
if (i.StartsWith(a) == false)
{
Console.WriteLine(i);
}
}
}
I want to output from the list and match in the test. If the test exists, then it will not be displayed. If there is no side output,But there may be a problem with my code, it will output the same value many times
The list contains aaaaa, according to logic, aaaaa should not be output
Try this:
List<string> list = new List<string>(){"bfd", "jy", "aaaaa", "ndnk", "ntfn", "gfm", "gfm", "mhgd5h", "srsr", "ntr", "mtmyt", "dmy", "mmy6", "ngn9d", "y6m1", "d8dm", "bbbbb", "tym", "dmj", "trsh", "tsr"};
List<string> test = new List<string>(){"aaaaa", "bbbbb", "ccccc", "ddddd", "eeeee", "fffff", "ggggg"};
foreach (var a in list)
{
if (!test.Contains(a))
{
Console.WriteLine(a);
}
}
There are simple solutions using LINQ. But since I assume this is an exercise, I will show you the detailed version using loops.
The problem is that the WriteLine is inside the inner loop. Therefore you will get many repetitions. Store the outcome of the test in a Boolean variable and place the display part after the inner loop.
foreach (var a in list)
{
bool found = false;
foreach (var i in test)
{
if (i.StartsWith(a))
{
found = true;
break; // Exit the inner loop
}
}
if (!found)
{
Console.WriteLine(a); // We must output a here since i out of scope.
}
}
Also, if you want to know whether a specific string is contained in the list, you should probably replace i.StartsWith(a) with i == a.
The code becomes easier to read, if you extract the list search into its own method
private bool IsInList(List<string> list, string item)
{
foreach (string s in list)
{
if (s == item)
{
return true;
}
}
return false;
}
Now, you don't need the Boolean variable any more
foreach (var a in list)
{
if (!IsInList(test, a))
{
Console.WriteLine(a);
}
}
I used !condition (pronounce: "not condition") instead of condition == false. It's terser.
I assume that this is an exercise. In production code you would simply use the built in method Contains of the list.
foreach (var a in list)
{
if (!test.Contains(a))
{
Console.WriteLine(a);
}
}
or even (as #mjwills suggests in his comment):
foreach (var a in list.Except(test)) {
Console.WriteLine(a);
}

Taking a set of items from a list and to perform some operation based on need

I have a list of items in a list. From that list I need to take the first 1000 items and need to submit the package and then again I need to take another 1000 and need to submit a package. If the list is not having 1000 I need to submit the package with all the items. for that I wrote the following code which is returning an error as collection modified.
List<SyncQueue> tempMassiveSyncQueue=massiveSyncQueue;
while (tempMassiveSyncQueue.Count != 0)
{
int MassivePackageFileCount =Convert.ToInt32(ConfigurationManager.AppSettings["MassivePackageFileLimit"]);
massiveSyncQueues = tempMassiveSyncQueue;
List<SyncQueue> tempMassivePackageSyncQueue=new List<SyncQueue>();
if (massiveSyncQueues.Count > 1000
{
var massivePackageSyncQueue = (massiveSyncQueues.Take(1000)).ToList<SyncQueue>();
tempMassivePackageSyncQueue = massivePackageSyncQueue;
SubmitPackage(massivePackageSyncQueue);
}
if (tempMassivePackageSyncQueue.Count != 0)
{
foreach (var massivesynq in tempMassiveSyncQueue)
{
foreach (var deleteId in tempMassivePackageSyncQueue.Where(id => id.SyncQueueId == massivesynq.SyncQueueId))
{
tempMassiveSyncQueue.Remove(massivesynq);
}
}
}
else
{
SubmitPackage(massiveSyncQueues);
}
massiveSyncQueues = null;
}
Can any one help on this?
Incorporate Skip into your logic
int loopCount = 0;
While(true)
{
var ListToProcess = massiveSyncQueue.Skip(loopCount*1000).Take(1000);
SubmitPackage(ListToProcess);
if(ListToProcess.Count < 1000) // We know there are no more in the list massive list.
{
break;
}
loopCnt++;
}
Your problem is that you are adjusting the collection on which the bounds of the foreach construct are set.
Try using ToList() on the collection you are looping through, as this creates a new List in memory:
foreach (var massivesynq in tempMassiveSyncQueue.ToList())
{
foreach (var deleteId in tempMassivePackageSyncQueue.Where(id => id.SyncQueueId == massivesynq.SyncQueueId).ToList())
{
tempMassiveSyncQueue.Remove(massivesynq);
}
}
In line 1 you set tempMassiveSyncQueue = massiveSyncQueue, yet within the while loop you set massiveSyncQueue = tempMassiveSync.
The collection modified error usually occurs when you modify the collection you are looping through. Which is why you need to first create a copy of the collection which is INDEPENDANT to the original collection and loop through that.
Before the while loop you need to add all items in massiveSyncQueue to tempMassiveSyncQueue. You then need to loop through the temp list with your code. In the second loop, you are removing items from the list you are looping through. I assume you meant to remove the items from massiveSyncQueue and not the temp list.
Try the following:
List<SyncQueue> tempMassiveSyncQueue = new List<SyncQueue>();
foreach(var item in massiveSyncQueue)
{
tempMassiveSyncQueue.Add(item);
}
while (tempMassiveSyncQueue.Count != 0)
{
int MassivePackageFileCount = Convert.ToInt32(ConfigurationManager.AppSettings["MassivePackageFileLimit"]);
List<SyncQueue> tempMassivePackageSyncQueue=new List<SyncQueue>();
if (massiveSyncQueues.Count > 1000
{
var massivePackageSyncQueue = (massiveSyncQueues.Take(1000)).ToList<SyncQueue>();
tempMassivePackageSyncQueue = massivePackageSyncQueue;
SubmitPackage(massivePackageSyncQueue);
}
if (tempMassivePackageSyncQueue.Count != 0)
{
foreach (var massivesynq in massiveSyncQueue)
{
foreach (var deleteId in tempMassivePackageSyncQueue.Where(id => id.SyncQueueId == massivesynq.SyncQueueId))
{
massiveSyncQueue.Remove(massivesynq);
}
}
}
else
{
SubmitPackage(massiveSyncQueues);
}
massiveSyncQueues = null;
}
Try this
int count=1;
while(tempMassivePackageSyncQueue.Count>1000)
{
var massivePackageSyncQueue = (massiveSyncQueues.skip(count*1000).Take(1000)).ToList<SyncQueue>();
tempMassivePackageSyncQueue = massivePackageSyncQueue;
SubmitPackage(massivePackageSyncQueue);
count++;
}
var massivePackageSyncQueue = (massiveSyncQueues.skip(count*1000).Take()).ToList<SyncQueue>();
tempMassivePackageSyncQueue = massivePackageSyncQueue;
SubmitPackage(massivePackageSyncQueue);

compare List<string> and List<T>

I'm using C# and framework 4.0.
I have a list of type string and another list of type class T;
How can I compare List with a List and save the difference?
private void simpleButton_Compare_Click(object sender, EventArgs e)
{
try
{
bool Is_Egal = true;
int i = 0;
foreach (string Od_Scan in Ordre_Scan)
{
if (!Outils.Get_Ordre_Donne()[i].NoOrdre.Contains(Od_Scan) && !String.IsNullOrWhiteSpace(Od_Scan))
{
Is_Egal = false;
Temp_Od_Scan.Add(Od_Scan);
}
i++;
}
foreach (Pers_Compare Od_Done in Outils.Get_Ordre_Donne())
{
if (!Ordre_Scan.Contains(Od_Done.NoOrdre) && !String.IsNullOrWhiteSpace(Od_Done.NoOrdre))
{
Is_Egal = false;
Temp_Od_Donne.Add(Od_Done);
}
else
{
Temp_Od_Donne_Egal.Add(Od_Done);
}
}
if (Is_Egal)
{
MessageBox.Show("égalité");
}
else
{
MessageBox.Show("PAS égalité");
}
}
catch (Exception excThrown)
{
MessageBox.Show(excThrown.Message);
}
}
and the data :
List<string> Ordre_Scan= new List<string> { "azer","qsdf"};
Pers_Compare obj = new Pers_Compare();
obj.Nolv = 1;
obj.Noordre = "qsdf"
Pers_Compare obj2 = new Pers_Compare();
obj2.Nolv = 1;
obj2.Noordre = "wxcv"
List<Pers_Compare> Ordre_Donne = new List<Pers_Compare>();
Ordre_Donne.add(obj);
Ordre_Donne.add(obj2);
And I want to save the data in Ordre_Donne but not in Od_Scan and vice versa.
foreach (string Od_Scan in Temp_Od_Scan)
{
all item that not found in List A
--> wxcv
}
foreach (var Od_Done in Temp_Od_Donne)
{
all item that not found in List B
--> azer
}
The answer given for a slightly different question (comparing a List with another List) seems to me to be a good solution for your issue, they address multiple issues to do with comparisons of lists.
EDIT: However you should be more specific with your requirements i.e. what exactly is a 'difference', e.g. is {1,1,2} and {1,2} the same?
Here is the answer given the most votes... (included here just encase it gets removed for some reason (as per Bob' suggestion))
"
DESCRIPTION:
I need to check that they both have the same elements, regardless of their position within the list. Each MyType object may appear multiple times on a list. Is there a built-in function that checks this? What if I guarantee that each element appears only once in a list?
EDIT: Guys thanks for the answers but I forgot to add something, the number of occurrences of each element should be the same on both lists.
ANSWER:
If you want them to be really equal (i.e. the same items and the same number of each item), I think that the simplest solution is to sort before comparing:
Enumerable.SequenceEqual(list1.OrderBy(t => t), list2.OrderBy(t => t))
Edit:
Here is a solution that performs a bit better (about ten times faster), and only requires IEquatable, not IComparable:
public static bool ScrambledEquals<T>(IEnumerable<T> list1, IEnumerable<T> list2) {
var cnt = new Dictionary<T, int>();
foreach (T s in list1) {
if (cnt.ContainsKey(s)) {
cnt[s]++;
} else {
cnt.Add(s, 1);
}
}
foreach (T s in list2) {
if (cnt.ContainsKey(s)) {
cnt[s]--;
} else {
return false;
}
}
return cnt.Values.All(c => c == 0);
}
Edit 2:
To handle any data type as key (for example nullable types as Frank Tzanabetis pointed out), you can make a version that takes a comparer for the dictionary:
public static bool ScrambledEquals<T>(IEnumerable<T> list1, IEnumerable<T> list2, IEqualityComparer<T> comparer) {
var cnt = new Dictionary<T, int>(comparer);
...
"
var list1 = Ordre_Donne.Where(o => !Ordre_Scan.Any(s => s == o.Noordre));
var list2 = Ordre_Scan.Where(s => !Ordre_Donne.Any(o => o.Noordre == s));
You can either implement IComparable on your Pers_Compare class, which will look something like:
public int CompareTo(string other)
{
return this.Noordre.CompareTo(other);
}
Or, if you don't have control of the data structure, you could do something like
var Temp_Od_Donne = from od in Ordre_Donne
where !Ordre_Scan.Contains(od.Noordre)
select od;
var Temp_Od_Scan = from os in Ordre_Scan
where !Ordre_Donne.Select(od => od.Noordre).Contains(os)
select os;

convert foreach loop to linq code

the below code is working as expected but I'm looking to convert the below code to use Linq?
any suggestions?
string[] selections = "Men,Women,Boys".Split(',');
int _chkboxId = 0;
int _chkboxTextId = 1;
try
{
string id = "lstchk_" + _chkboxId;
while (!driver.FindElement(By.Id(id)).Equals(null))
{
string checkboxId = String.Format("lstchk{0}", _chkboxTextId);
string checkboxName = driver.FindElement(By.Id(checkboxId)).Text;
foreach (string match in selections)
{
if (checkboxName == match.Trim())
{
//matched... do more work here...
}
}
}
foreach (string match in selections.Where(match => checkboxName == match.Trim()))
{
//matched... do more work here...
}
If your selections list contains only distinct values, than you could use
if(selections.Any(match=>match.Trim().Equals(checkboxName)))
{
//Do work
}
instead of your loop. Same if your list may contain non-distinct values, but the work should be done only once for each checkboxName
switch(checkboxName) {
case "Men":
case "Women":
case "Boys":
// do more work here
default:
// no match, bail
}
Sometimes, there's just a different way to write the code.
How would you convert this simple foreach to a linq statement?
public List<string> GetItems()
{
var items = new List<string>();
foreach (Ranorex.ListItem item in ranorexComboBox.Items)
{
items.Add(item.Text);
}
return items;
}

How to skip a specific position within a for each loop in c sharp?

List<string> liste = new List<String>
{
"A","B","C","D"
};
foreach (var item in liste)
{
System.Diagnostics.Debug.WriteLine(item.ToString());
}
for (int i = 0; i < liste.Count; i++)
{
if (i == 0)
continue;
System.Diagnostics.Debug.WriteLine(liste[i].ToString());
}
How do i skip a specific position in a foreach loop? I do not want to evaluate any values, but just skip the position x.
It has to be a specific position. One could choose position 0 or maybe position 7.
It is very easy to skip the first item in the list:
foreach(var item in list.Skip(1))
{
System.Diagnostics.Debug.WriteLine(item.ToString());
}
If you want to skip any other element at index n, you could write this:
foreach(var item in list.Where((a,b) => b != n))
{
System.Diagnostics.Debug.WriteLine(item.ToString());
}
In this example I use a lambda expression that takes two arguments: a and b. Argument a is the item itself, while argument b is the index of the item.
The relevant pages on MSDN that describe these extension methods are:
IEnumerable.Skip()
IEnumerable.Where()
You could even write your own extension method that allows you to skip an element in a list:
public static class MyEnumerableExtensions
{
public static IEnumerable<T> SkipAt<T>(this IEnumerable<T> list, int index)
{
var i = 0;
foreach(var item in list)
{
if(i != index)
yield return item;
i++;
}
}
}
This will allow you to write something like this to skip an item:
foreach(var item in list.SkipAt(2))
{
System.Diagnostics.Debug.WriteLine(item.ToString());
}
A foreach loop iterates over a collection that implements IEnumerable. The enumerator exposes the current item and a method to move onto the next item - it has no concept of an index.
You could always do:
var i = 0;
foreach (var item in liste) {
if (i++ == skip) continue;
Debug.WriteLine(item.ToString());
}
But this seems unnecessarily contrived. If you need an index, go with a for loop.
The other option is to remove the undesired item from the List before iterating:
foreach (var item in liste.Take(n-1).Union(liste.Skip(n))) {
Debug.WriteLine(item.ToString());
}
I love list's .ForEach, here's my take using #Elian's .SkipAt(n) and .ForEach:
var list = new List<String> { "A", "B", "C", "D" };
list = list.SkipAt(1).ToList();
list.ForEach(Debug.WriteLine);
You should try using the enhanced version of the Where extension method that allows you to filter on item and index.
Check the reference.
http://msdn.microsoft.com/en-us/library/bb549418.aspx
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Verbatim list");
List<string> list = new List<String> { "A","B","C","D" };
foreach (var item in list)
{
Console.WriteLine(item.ToString());
}
Console.WriteLine("Filtered list");
int itemToSkip = 2;
foreach (var item in list.Where((item, index) => index != itemToSkip))
{
Console.WriteLine(item.ToString());
}
Console.ReadKey();
}
}
}
This will give you the following output.
Verbatim list
A
B
C
D
Filtered list
A
B
D
To skip a position inside the foreach loop, one option is that you can skip the action inside the foreach loop by using an if statement, like
foreach(var item in liste)
{
if (item != 'X')
{
//do something
}
}
But i am waiting for better solutions

Categories