tags:

views:

143

answers:

4

i have an array of objects (Car[] for example) and there is an IsAvailable Property on the object

i want to use the full array (where IsAvailable is true for some items and false for some others) as the input and return a new array which includes only the items that have IsAvailable = true.

+7  A: 

If you're using C# 3.0 or better...

public Car[] Filter(Car[] input)
{
    return input.Where(c => c.IsAvailable).ToArray();
}

And if you don't have access to LINQ (you're using an older version of .NET)...

public Car[] Filter(Car[] input)
{
    List<Car> availableCars = new List<Car>();

    foreach(Car c in input)
    {
        if(c.IsAvailable)
            availableCars.Add(c);
    }

    return availableCars.ToArray();
}
Justin Niessner
Considering the LINQ implementation is built on IQueryable, how could its implementation be any better than the List based one?
LorenVS
IEnumerable*** (15chars)
LorenVS
It's not. I posted it in case the OP was using an older version of .NET. If the OP needs the most performant code, they can at least get the idea from the second example...and optimize it to suit their needs.
Justin Niessner
Your comment at the end was a little misleading... my bad...
LorenVS
Posted another edit to try to clear things up...any better?
Justin Niessner
Nope :), still confused... I'm wondering why you are stating performance concerns on the second approach but not on the first... (just nitpicking, I think your solution is great)...
LorenVS
In the second example, I used a List<T> to store the elements and then output them using the .ToArray() method. I would imagine there has to be a cleaner way to do the work...and I'd hope that if one existed, LINQ to Objects would use it. I'd break out Reflector, but I'm on my Mac at the moment.
Justin Niessner
I'll save you the trouble :) Linq to Objects uses essentially an inlined array based list (doesn't use List<T> directly, but performs a standard array doubling algorithm)
LorenVS
And then copies the result into a new array. So it is essentially the same as your solution above...
LorenVS
+1  A: 

Easiest way:

Car[] cars = //...
Car[] filtered = cars.Where(c => c.IsAvailable).ToArray();

Possibly More Efficient:

Car [] cars = //...
    List<Car> filteredList = new List<Car>();
    for(int i = 0; i < cars.Length; i++)
    {
        if(cars[i].IsAvailable)
           filteredList.Add(cars[i]);
    }
    Car[] filtered = filteredList.ToArray();
LorenVS
+1  A: 

A simple solution is to create a new array, loop through the input array and add only those items which satisfy your conditions to the new array, and return the new array:

List<Car> available = new List<Car>();
foreach (Car c in cars) {
    if (c.IsAvailable) {
        available.add(c);
    }
}
//Here you can either just return the list, or create an array from it.
goatlinks
you got the java foreach I believe...
LorenVS
Aww drat. You're right =)
goatlinks
A: 

var available = from c in cars where c.IsAvailable == true select c;

Or

var available = cars.Where(c => c.IsAvailable == true);

Jim Wallace