pzozulka
asked on
C#.NET: loop through a collection to filter out items
I have a collection called CurrentAddressCollection which I need to loop through to filter out certain items, and then return that same collection. However, this filter should only apply when a certain condition is true, otherwise just return the collection as is.
I thought about using LINQ, like my example below, but it didn't work because LINQ returns an IEnumerable<Address> collection which is not the same type as the CurrentAddressCollection. And when I try to cast the IEnumerable collection as DomainList it returns null.
Question:
After using linq to filter out a collection, how do I get my collection to be of the same type before linq was applied?
More Info:
AddressHack is an abstract class that inherits from DomainList.
DomainList is an abstract class that has the ToArray() method:
I thought about using LINQ, like my example below, but it didn't work because LINQ returns an IEnumerable<Address> collection which is not the same type as the CurrentAddressCollection. And when I try to cast the IEnumerable collection as DomainList it returns null.
Question:
After using linq to filter out a collection, how do I get my collection to be of the same type before linq was applied?
...
gridAddresses.DataSource = GetDataSource().ToArray();
...
private DomainList GetDataSource()
{
if (CurrentAddressCollection.ListOwner is CustomerQuote)
{
var addresses = CurrentAddressCollection.Cast<Address>().Where(a => a.AddressName != "ABC");
return addresses as DomainList;
}
return CurrentAddressCollection;
}
public AddressHack CurrentAddressCollection
{
get{return _currentAddressCollection;}
set{_currentAddressCollection = value;}
}
More Info:
AddressHack is an abstract class that inherits from DomainList.
DomainList is an abstract class that has the ToArray() method:
public virtual DomainObject[] ToArray()
{
return (DomainObject[]) List.ToArray(typeof(DomainObject));
}
Have you thought about the AutoMapper?
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
@kaufmed
and then return that same collection
Am I missing something?
and then return that same collection
Am I missing something?
I dunno... I had a little trouble following the code supplied, but I thought "same collection" meant the same type of CurrentAddressCollection. Regardless of the type, if it's not List or array, then custom code is needed.
And if he indeed means to filter the existing collection, then removing the items as you suggest is feasible.
And if he indeed means to filter the existing collection, then removing the items as you suggest is feasible.
First in place, what is the connection between AddressHack and Address? The CurrentAddressCollection is of type AddressHack. But you cast it to Address.
Assuming that all elements of CurrentAddressCollection are compatible with DomainList. If so, try..
If only few elements are compatible with DomainList then try below...
Otherwise try below...
HTH.
Assuming that all elements of CurrentAddressCollection are compatible with DomainList. If so, try..
var addresses = CurrentAddressCollection.Cast<DomainList>().Where(a => a.AddressName != "ABC");
If only few elements are compatible with DomainList then try below...
var addresses = CurrentAddressCollection.OfType<DomainList>().Where(a => a.AddressName != "ABC");
Otherwise try below...
var addresses = CurrentAddressCollection.OfType<Address>().Where(a => a.AddressName != "ABC");
return addresses as DomainList;
HTH.
ASKER
käµfm³d: Your understanding was correct in that after applying the linq code, I was hoping to get the same TYPE of collection back, instead of an IEnumerable.
Easwaran Paramasivam: The relationship is as follows:
public AddressHack CurrentAddressCollection { get; set; }
public abstract class AddressHack : DomainList, IAddressHack
{
...
}
public class AddressCollection<T> : AddressHack where T : Address, new()
{
...
}
Here's the code I tried to debug:
Easwaran Paramasivam: The relationship is as follows:
public AddressHack CurrentAddressCollection { get; set; }
public abstract class AddressHack : DomainList, IAddressHack
{
...
}
public class AddressCollection<T> : AddressHack where T : Address, new()
{
...
}
Here's the code I tried to debug:
// ToArray() is a virtual method in the DomainList class.
// CurrentAddressCollection is a "AddressHack", and "AddressHack" is a "DomainList"
grdAddresses.DataSource = GetDataSource().ToArray();
grdAddresses.DataBind();
private DomainList GetDataSource()
{
if (condition == true)
{
var a = CurrentAddressCollection.OfType<Address>().Where(a => a.AddressName != "ABC");
var b = a as DomainList;
return b;
}
return CurrentAddressCollection;
}
After executing the linq code, a contains an IEnumerable collection of type <Address>. After executing the following line, b is null.
>>then return that same collection.
In future please ask for what you want. You are now asking for a different (new) collection to be returned.
Just what is the collection? If it is a List then you could make a clone then use RemoveAll as I suggested previously.
For clone:
http://stackoverflow.com/questions/222598/how-do-i-clone-a-generic-list-in-c
eg.
var newList = oldList.ToList();
In future please ask for what you want. You are now asking for a different (new) collection to be returned.
Just what is the collection? If it is a List then you could make a clone then use RemoveAll as I suggested previously.
For clone:
http://stackoverflow.com/questions/222598/how-do-i-clone-a-generic-list-in-c
eg.
var newList = oldList.ToList();
ASKER
Andy, as of now, it seems that your solution seems to be the only one that would work, but at this point, I'm just trying to learn to see if the original collection type (less filtered out items) can be returned using the linq code above.
I use linq often, particularly in this context, to filter collections. From what I've gathered here, this is not possible without custom code.
I use linq often, particularly in this context, to filter collections. From what I've gathered here, this is not possible without custom code.
I try not to use linq if I can do it easily by traditional ways. (I can usually rapidly scan and see errors in code but as soon as I come to linq or delegates I have to stop and think hard just what it is doing and what it is meant to do - not necessarily the same).
Use tools appropriate to the job.
Use tools appropriate to the job.