How to Get a Sublist in C#
Asked Answered
S

6

117

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?

Smiga answered 11/11, 2009 at 4:17 Comment(2)
Can you show us a code sample of what you have, or clarify? I'm not following the question.Gesture
I have a list say List<String> list = new list<String>(); i need to take a sublist out of this list say from index 2 to length-1..Smiga
T
181

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);
}
Turgeon answered 11/11, 2009 at 4:22 Comment(2)
You cannot remove items from a list while iterating over them with a foreach.....!Mini
Slugster; I'm iterating over list 'b' while deleting from list 'a'. It's legal :)Turgeon
R
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();
Rodneyrodolfo answered 11/11, 2009 at 4:25 Comment(3)
This is a copy of the segment of the original list, not a view over a portion of the original list.Mukluk
@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!Rodneyrodolfo
I (like some other people) 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.Mukluk
T
6

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.

Telegenic answered 2/5, 2019 at 9:34 Comment(0)
M
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");
Mini answered 11/11, 2009 at 4:26 Comment(1)
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));Mini
B
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.

Bhutan answered 11/11, 2009 at 4:28 Comment(0)
A
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

Adamo answered 11/11, 2009 at 4:45 Comment(1)
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?Hubie

© 2022 - 2024 — McMap. All rights reserved.