Loop through List with Linq condition - c#

The code below works successfully to loop through a List. How do I add a where clause such that only for list items where sType = "File"
for (int i = 0; i < MyGlobals.ListOfItemsToControl.Count; i++) // Loop through List with for
Pseudo Code for what i want
for (int i = 0; i < MyGlobals.ListOfItemsToControl.Count.Where(y => y.sType == "File"); i++) // Loop through List with for

use LINQ to obtain a new filtered List that only contains the items that fit your condition:
var filteredList = MyGlobals.ListOfItemsToControl.Where(i => i.sType == "File").ToList();
for (var i = 0; i < filteredList.Count; i++) // Loop through List with for
...

In addition to sjkm's answer, if you're not using the index, just use a foreach loop.
foreach(var item in MyGlobals.ListOfItemsToControl.Where(i => i.sType == "File"))
{
// Do something with item.
}

Related

Adding to List<string> but having trouble with the items getting added

I have 2 lists with 200 items in each.
List A contains the names of the products.
List B contains the prices of the products.
I have another list (List C) with 250 items inside which include names and prices of products.
Now, I am trying to compare the names of List A to see if they exist in List C and if they do I want to use the price in List C.
This is what I've tried so far:
foreach (var item in wiznzList)
{
for (int j = 0; j < nameList.Count; j++)
{
if (nameList[j] == item.ProductName)
{
wizNzPriceList.Add(item.Price);
}
else
{
wizNzPriceList.Add("No Product");
}
}
}
I want to go through the list of names and check if they exist in List C if they do I want to add the price from List C and if it doesn't exist I want it to write No Product.
So, in the end I want 3 lists with 200 items in each.
Instead, when I run this I get 10040000 items added into the list. Could someone please point me in the right direction.
If i understand your problem correctly (and the jury is out on that)
You could use ToDictionary and Select
var dict = products.ToDictionary(x => x.ProductName, x => x.Price);
var results = names.Select(x => dict.TryGetValue(x, out var value) ? value.ToString() : "No Product");
Note : You could use Any for O(n^2) time complexity. However, ToDictionary would be more efficient
I have found a code that does what you want it to do !
Object Product(string pName, float pPrice).
listA list of Products so you can store and change price.
listB list of float, not used.
list C list of Products with pName and pPrice.
The CompareA_With_C() method first checks for same products and if true put price of list C in listA and breaks out of inner loop.
The else if statement waits till the loop has gone through the whole of listC and if no pName match found, changes pName to "No Product" in listA.
Code :
void CompareA_With_C()
{
for (int i = 0; i < listA.Count; i++)
{
for (int j = 0; j < listC.Count; j++)
{
string a = listA[i].pName;
string c = listC[j].pName;
if (string.Equals(a, c))
{
listA[i].pPrice = listC[j].pPrice;
break;
}
else if (j == (listC.Count - 1))
{
listA[i].pName = "No Product";
listB[i] = 0.0f;
}
}
}
}
You can try to use LINQ and replace your inner loop with Any method.
foreach (var item in wiznzList)
{
if (nameList.Any(p => p == item.ProductName)
{
wizNzPriceList.Add(item.Price);
}
else
{
wizNzPriceList.Add("No Product");
}
}
I was able to solve my problem by using the code below, Thank you very much Crispi.
for (int i = 0; i < nameList.Count; i++)
{
for (int j = 0; j < wiznzList.Count; j++)
{
string a = nameList[i];
string c = wiznzList[j].ProductName;
if (string.Equals(a, c))
{
wizNzPriceList.Add(wiznzList[j].Price);
break;
}
else if (j == (wiznzList.Count - 1))
{
wizNzPriceList.Add("No Product");
}
}
}
I now get 200 results as required. Thank you everyone for your time.

How update a list in a foreach

I have a foreach of a List and i want to Update the list or (i don´t know wich is better) create a new one with the new values. How to do this ?
My code is bigger than this because i am decrypting, but if help me with this simple, will fix the other.
foreach (Envolvido envolvido in ListaDados.ItemsSource)
{
for (int i = 0; i < ListaDados.ItemsSource.OfType<object>().Count(); i++)
{
var suspid = Convert.FromBase64String(envolvido.SUSPID);
var ivnome = Convert.FromBase64String(envolvido.IVNOME);
}
}
So, with the help of all, i got the correct answer !
List<Envolvido> mylist = t.Result;
for (int index = 0; index < mylist.Count(); index++)
{
var items = mylist.ToList();
Envolvido envolvido = items[index];
envolvido.SUSPID= Convert.FromBase64String(envolvido.SUSPID);
envolvido.IVNOME = Convert.FromBase64String(envolvido.IVNOME);
}
THANKS!
Use for for modifing lists. NOT foreach.
As it says on MSDN:
The foreach statement is used to iterate through the collection to get the information that you want, but can not be used to add or remove items from the source collection to avoid unpredictable side effects. If you need to add or remove items from the source collection, use a for loop.
List<Envolvido> mylist = t.Result;
for (int index = 0; index < mylist.Count(); index++)
{
var items = mylist.ToList();
Envolvido envolvido = items[index];
envolvido.SUSPID= Convert.FromBase64String(envolvido.SUSPID);
envolvido.IVNOME = Convert.FromBase64String(envolvido.IVNOME);
}

Handling multiple lists with if/else condition - recursion

i have many lists which contain 1 or more objects, and if there is more then 1 object in the list, it should do something. When there is only 1 object in the list, then take the second list and do the same. This should happen for 4 lists.
This is my Solution, but i think this is a bad solution. Is there a far better way on handling this code?
if (list1.Count > 1)
for (int i = 0; i < list1.Count; i++)
{
DoSomething(list1);
}
else
{
if (list2.Count > 1)
for (int i = 0; i < list2.Count; i++)
{
DoSomething(list2);
}
else
{
if (list3.Count > 1)
for (int i = 0; i < list3.Count; i++)
{
DoSomething(list3);
}
else
{
...
Many thanks and best regards,
Joerg
// using System.Collections.Generic;
// using System.Linq;
// create an enumerable "list" of your lists (however many there are):
var lists = new[] { list1, list2, list3, … };
// find the first list that has more than 1 element:
var list = lists.FirstOrDefault(_ => _.Count() > 1);
// if there is such a list…
if (list != null)
{
// … then `DoSomething` to each of its items:
foreach (var item in list)
{
DoSomething(item);
}
}
I tried to use same psuedo-code style as OP. The logic replicates the original, but in condensed form and with advantage of easily adding lists to the master list array (as suggested by #Benjamin).
It is assumed that DoSomething is a single function applied to the first list which has Count > 1. If you wanted to apply a custom function per list, you could create another array for holding the function to call for the corresponding list.
listArray = new[] {list1, list2, list3, list4}; // you can add more as needed to this master array
for (int i = 0; i < listArray.Count; i++)
{
if (listArray[i].Count > 1)
{
for (int i = 0; i < listArray.Count; i++)
{
DoSomething(listArray[i]);
}
break; // http://msdn.microsoft.com/en-us/library/adbctzc4.aspx
}
}
You can check first which list you want to use:
var lists = new[]{ list1, list2, list3, list4 };
var list = lists.FirstOrDefault(l => l.Count > 1);
if(list != null)
{
list.ForEach(l => DoSomething(list));
}
Seems like you need the first list for which Count > 1.
Also, inside the for-loop, you're saying DoSomething(list1);. I think it should be DoSomething(list1[i]);
var lists = new [] { list1, list2, list3, list4 };
var target = lists.FirstOrDefault(l => l.Count() > 1);
if (target != null) {
for (int i = 0; i < target.Count; i++)
{
DoSomething(target[i]);
}
} else {
//...
}

Loop inside a array within a dictionary

Hi I have a quick question, which is the easiest way to loop inside an array that is within an object in a dictionary using C#?
The dictionary contain groups and groups have an array called tags, I have search for a tag and return a list of groups that contain that tag
I created a solution but it returns too many doubles when I apply it.
List<Programme> toReturn = new List<Programme>();
// might need to ask getprogramme service to do the iteriation and retun a value
foreach (Programme programme in programmes.Values)
{
if (message.Programme.Tags[0] != null)
{
int i;
int u;
foreach (KeyValuePair<string, Programme> entry in programmes)
{
// for (i = 0; i < message.Group.Tags.Length; i++)
for (i = 0; i < entry.Value.Tags.Length; i++)
//foreach (string i in message.Group.Tags)
{
for (u = 0; u < message.Programme.Tags.Length; u++)
{
// Compare the Name of the entry to the Name in the message (string comparison)
if (entry.Value.Tags[i].Equals(message.Programme.Tags[u]))
{
// If we found the group, set the return value and then break from the loop
toReturn.Add(programme);
break;
}
}
}
}
}
The easiest way is to use LINQ:
var res = groups.Where(g => g.Value.Any(t => t.Equals("search_tag")));

Looping through x number of arrays

How do I loop through x number of arrays and visit all combinations of all cells in all of the arrays? The problem here is there can be x number of arrays of some items inside. For instance,
List<List<string>> _arrays = GetArrayInformation();
I want to compare all the string inside each array with all the other arrays and the strings inside of each array. Do I use while like
while(i < _arrays.Count)
Thanks for your answer. The answer seems simple but when you think about it is kind of tricky and hard.
Update:
Thanks for your answers. I can do this with a 3 arrays like
for(int i = 0; i < _arrays[0].Count; i++) {
for(int l = 0; l < _arrays[1].Count; l++) {
for(int m = 0; m < _arrays[2].Count; m++) {
string _hello = _arrays[0][i] + "|" + _arrays[1][l] + "|" + _arrays[2][m];
}
}
}
Because I have dynamic number of arrays, it gets tricky.
foreach(var array in _arrays)
{
foreach(var s in array)
{
foreach(var otherArray in _arrays)
{
if(otherArray == array) continue;
if(otherArray.Contains(s)) {} // not sure what you want to do
}
}
}
this will loop through every single string seeing if it is in any other array.... it's the straightforward approach, but not very efficient and will duplicate work.
There is no enough information is here
If you need to find elements that exists in few array You will use something like this:
var multipleWords = _arrays
.SelectMany(items => items.Distinct())
.GroupBy(item => item)
.Select(group => new {Item = group.Key, Count = group.Count()})
.Where(item => item.Count > 1)
.Select(item => item.Item)
.ToArray();
multipleWords will contain each word from the all these arrays that exists in two or more arrays
You could use a recursive search function.
public Search<T>(object o, string comparestring)
{
if(o is List<string>)
{
//Compare to your string
}
else
{
//Call this search function with the type of the object in the list.
//Will iterate through all of your strings recursively.
Type t = o.GetType().GetGenericArguments()[0];
foreach( object osub in (T)o)
Search<t>( ((t)o),comparestring)
}
}

Categories