Tripping
Tripping

Reputation: 929

count non-null elements of IEnumerable<HttpPostedFileBase>

I have a view model in asp .net mvc 3 which has

IEnumerable<HttpPostedFileBase> files

In the view, I have a for loop that creates 9 input tags for these files.

I want to implement a check on the server-side to ensure atleast 3 files are being uploaded.

I tried putting a condition

if(files.Count() > 2) { // code here } 

However, that returns 9 as it also counts the null elements.

I can think of implementing a counter myself as below:

int count = 0;
@foreach(var file in files) {
  if(file != null && file.ContentLength > 0) { 
    count++; 
  }
}

Is this the best way to do this or is there a functionality already in asp .net mvc for this.

Upvotes: 2

Views: 1927

Answers (3)

Servy
Servy

Reputation: 203827

Any time you see the paradigm of enumerable.Count() > X you could use the following method which gives you the benefit of ending as soon as you know you have enough items:

public static bool HasAtLeast<T>(IEnumerable<T> source, int number)
{
    return source.Skip(number - 1).Any();
}

Given that method you could write:

if(files.Where(file => file != null && file.ContentLength > 0)
    .HasAtLeast(2))
{
    //code goes here
}

Now, is this a major improvement, no, probably not. You'd need to either be executing this code many, many thousands of times, have a gigantic enumeration, or have an enumeration that is expensive to enumerate (if it's the result of a LINQ query performing long running methods for example) for it to matter. If you didn't put HasAtLeast into it's own method it would also decrease readability, so that alone wouldn't be worth the (usually small) performance advantage.

Upvotes: 1

McGarnagle
McGarnagle

Reputation: 102783

Use a predicate to filter the count:

files.Where(file => file != null).Count()

Or simpler, just files.Count(file => file != null).

Upvotes: 4

L.B
L.B

Reputation: 116168

files.Count(file=>file != null && file.ContentLength > 0);

Upvotes: 6

Related Questions