115

I have a List<String> and i need to take a sublist out of this list. Is there any methods of List available for this in .NET 3.5?

Prince
  • 20,353
  • 6
  • 39
  • 59
Thomas Manalil
  • 1,657
  • 4
  • 16
  • 23

6 Answers6

179

You want List::GetRange(firstIndex, count).

// I have a List called list
List sublist = list.GetRange(5, 5); // (gets elements 5,6,7,8,9)
List anotherSublist = list.GetRange(0, 4); // gets elements 0,1,2,3)

Is that what you're after?

If you're looking to delete the sublist items from the original list, you can then do:

// list is our original list
// sublist is our (newly created) sublist built from GetRange()
foreach (Type t in sublist)
{
    list.Remove(t);
}
Pang
  • 9,564
  • 146
  • 81
  • 122
Josh
  • 3,540
  • 1
  • 21
  • 12
7

Would it be as easy as running a LINQ query on your List?

List<string> mylist = new List<string>{ "hello","world","foo","bar"};
List<string> listContainingLetterO = mylist.Where(x=>x.Contains("o")).ToList();
p.campbell
  • 98,673
  • 67
  • 256
  • 322
  • 2
    This is a copy of the segment of the original list, not a view over a portion of the original list. – Asad Saeeduddin Feb 08 '15 at 21:46
  • @Asad The point of this answer was to illustrate that the OP could use LINQ. You've pointed out that it creates a copy. Fantastic. Your talents could probably be better used in editing this question to illustrate the point even finer than I had left it 5.5 years ago. If you edit it, you'll get credit in the internet justice league of pedantry, and it'll be well earned! – p.campbell Feb 08 '15 at 23:55
  • 15
    I ([like some other people](http://stackoverflow.com/questions/1287340/net-equivalent-of-javas-list-sublist)) was looking for something similar to `subList` from Java, which exposes a mutable view into the original list. This behaves differently, which might not be immediately obvious, so I thought it would be helpful to point it out for the benefit of anyone who sees this later. Off topic, you might want to take up yoga or meditation or something; you went 0 to red-in-the-face mad without any provocation whatsoever. – Asad Saeeduddin Feb 09 '15 at 00:29
5

With LINQ:

List<string> l = new List<string> { "1", "2", "3" ,"4","5"};
List<string> l2 = l.Skip(1).Take(2).ToList();

If you need foreach, then no need for ToList:

foreach (string s in l.Skip(1).Take(2)){}

Advantage of LINQ is that if you want to just skip some leading element,you can :

List<string> l2 = l.Skip(1).ToList();
foreach (string s in l.Skip(1)){}

i.e. no need to take care of count/length, etc.

jw_
  • 1,663
  • 18
  • 32
3

Use the Where clause from LINQ:

List<object> x = new List<object>();
x.Add("A");
x.Add("B");
x.Add("C");
x.Add("D");
x.Add("B");

var z = x.Where(p => p == "A");
z = x.Where(p => p == "B");

In the statements above "p" is the object that is in the list. So if you used a data object, i.e.:

public class Client
{
    public string Name { get; set; }
}

then your linq would look like this:

List<Client> x = new List<Client>();
x.Add(new Client() { Name = "A" });
x.Add(new Client() { Name = "B" });
x.Add(new Client() { Name = "C" });
x.Add(new Client() { Name = "D" });
x.Add(new Client() { Name = "B" });

var z = x.Where(p => p.Name == "A");
z = x.Where(p => p.Name == "B");
John Saunders
  • 160,644
  • 26
  • 247
  • 397
slugster
  • 49,403
  • 14
  • 95
  • 145
  • After you elaborated, use my first example and add this: z = x.GetRange(1, 3); x.RemoveRange(1, 3); x.AddRange(z.OrderByDescending(p => p)); – slugster Nov 11 '09 at 04:37
0

Your collection class could have a method that returns a collection (a sublist) based on criteria passed in to define the filter. Build a new collection with the foreach loop and pass it out.

Or, have the method and loop modify the existing collection by setting a "filtered" or "active" flag (property). This one could work but could also cause poblems in multithreaded code. If other objects deped on the contents of the collection this is either good or bad depending of how you use the data.

Doug L.
  • 2,676
  • 1
  • 19
  • 33
0

Reverse the items in a sub-list

int[] l = {0, 1, 2, 3, 4, 5, 6};
var res = new List<int>();
res.AddRange(l.Where((n, i) => i < 2));
res.AddRange(l.Where((n, i) => i >= 2 && i <= 4).Reverse());
res.AddRange(l.Where((n, i) => i > 4));

Gives 0,1,4,3,2,5,6

John Saunders
  • 160,644
  • 26
  • 247
  • 397
Phillip Ngan
  • 15,482
  • 8
  • 63
  • 79
  • `Range` is true with integer datatype. what if your datatype is `DataTime` and you need to retrieve a list of records between two specific dates? – Jogi Jun 24 '16 at 13:42