tags:

views:

282

answers:

6

I have the following code

foreach (var rssItem in rss.Channel.Items)
{
    // ...
}

But only want 6 items not all items, how can I do it in C#?

+24  A: 

just iterate over the top 6 from the collection:

foreach(var rssItem in rss.Channel.Items.Take(6))
statichippo
lol too slow :p
Codesleuth
When you say "too slow", are you referring to the time it takes to iterate over the collection or too slow to post the answer ?
Scott Davies
+3  A: 
rss.Channel.Items.Take(6)
Wouter
+5  A: 

Use Enumerable.Take:

foreach(var rssItem in rss.Channel.Items.Take(6)) {
    // go time!
}

Note that

rss.Channel.Items.Take(6)

does not do anything except instantiate an implementation of IEnumerable that can be iterated over to produce the first six items in the enumeration. This is the deferred execution feature of LINQ to Objects.

Note further that this assumes .NET 3.5. If you are working with an earlier version of .NET, you could use something along the lines of the following:

static IEnumerable<T> Take<T>(IEnumerable<T> source, int take) {
    if (source == null) {
        throw new ArgumentNullException("source");
    }
    if (take < 0) {
        throw new ArgumentOutOfRangeException("take");
    }
    if (take == 0) {
        yield break;
    }
    int count = 0;
    foreach (T item in source) {
        count++;
        yield return item;
        if (count >= take) {
            yield break;
        }
    }
}

Then:

foreach(var rssItem in Take(rss.Channel.Items, 6)) {
    // go time!
}

This assumes .NET 2.0. If you're not using .NET 2.0 you should seriously consider upgrading.

Jason
yield isn't in C# 2, Take would have to build and return a new IEnumerable<T> to work if the developer is still using VS2005.
Chris Charabaruk
No, `yield` is C# 2.0. Iterators were introduced in C# 2.0/.NET 2.0. cf. http://msdn.microsoft.com/en-us/library/dscyy5s0(VS.80).aspx and http://msdn.microsoft.com/en-us/library/9k7k7cf0(VS.80).aspx
Jason
+9  A: 

Not to be too obvious but...

int max = Math.Min(6, rss.Channel.Items.Count);
for (int i = 0; i < max; i++)
{
   var rssItem = rss.Channel.Items[i];
   //...
}

I know it's old school, and not filled with all sorts of Extension method goodness, but sometimes the old school still works... especially if you're still using .NET 2.0.

Nick
What if the sequence doesn't have an indexer? Suppose it is an infinite sequence of randomly-generated numbers, for example.
Eric Lippert
It'll still work for a list or array, which rss.Channel.Items probably is. Obviously "Take" is more simple if Linq is an option.
Meta-Knight
I suggest a language improvement for version 5.0 maybe. for(;;), ++ operators and the like would need setting 'oldschool' context, something like current 'unsafe'
George Polevoy
As I said... sometimes Linq and Extension methods are not an option b/c of the framework version you are working on.
Nick
+1, sometimes you can't always use the latest and greatest! :)
Joshua
You can use extension methods with .Net 2.0 as long as you are using VS2008 or above. Just create a class called System.Runtime.CompilerServices.ExtensionAttribute that inherits from Attribute. You can even get linq to work if you create extension methods with the correct names.... but this would be way too much work.
Matthew Whited
@Matthew: It might be a lot of work, but luckily somebody else has already done it: http://www.albahari.com/nutshell/linqbridge.aspx
LukeH
+1  A: 

If you're interested in a condition (i.e. ordering by date created)

foreach(var rssItem in rss.Channel.Items.OrderByDescending(x=>x.CreateDate).Take(6)) 
{
//do something
}

Perhaps if you want to get those created by a certain user, with that same sort

foreach(var rssItem in rss.Channel.Items
                          .Where(x=>x.UserID == 1)
                          .OrderByDescending(x=>x.CreateDate)
                          .Take(6)) 
{
//do something
}
p.campbell
+1  A: 

You could also just break out of the loop if you don't want to use linq.

        int count = 0;
        foreach (var rssItem in rss.Channel.Items)
        {
            if (++count == 6) break;
            ...
        }
mdm20