Roberto Ruggeri
Roberto Ruggeri

Reputation: 79

Splitting a list c#

Hi I'm a little bit stuck in C#. I'm new on it. This is my problem:

I have a list made up of 63 double numbers (let's call it "big list").

I want to split this list in 6 list with the following rule:

The first list consists of the first 8 elements of the big list; The second list goes from the 9th element of the big list to the (9+8=17th) element of the big list; The third list goes from the 18th element of the big list to the (18+8+1=27th) element of the big list; The fourth list goes from the 28th element of the big list to the (28+8+2=38th) element of the big list; The fifth list goes from the 39th element of the big list to the (39+8+3=50th) element of the big list; The sixth list goes from the 51th element of the big list to the (51+8+4=63th) element of the big list;

How can I do it? thanks a lot in advance for your help!

i've tried in this way but it gives me error "cannot apply indexing with [] to an expression of type method group"

List listsplitted = new List();

        for (int i = 0; i < 6; i++)
        {
            for (int j = 8; j < 8 + i + 1; j++)
            {
                Listsplitted[i] = biglist.Take[j];
            }
        }

Upvotes: 2

Views: 3676

Answers (4)

Alexander Petrov
Alexander Petrov

Reputation: 14231

If you can replace the list with an array, you can do without copying the data. You can use ArraySegment (or Span/Memory in newer versions of the language) to do this.

var array = Enumerable.Range(0, 63).Select(i => (double)i).ToArray();

var splitted = new List<ArraySegment<double>>();

int offset = 0;
int count = 8;
for (int i = 0; i < 6; i++)
{
    splitted.Add(new ArraySegment<double>(array, offset, count));
    offset += count;
    count++;
}

// see what we have
foreach (var seg in splitted)
    Console.WriteLine(seg.Offset + " " + seg.Count);

// work with segments
var segment = splitted[3];
segment[5] = 555555;

// the main array has also changed
Console.WriteLine(string.Join(" ", array));

Note that the segments do not store copies of the data, but refer to the data in the main array.

Upvotes: 0

E.Praneeth
E.Praneeth

Reputation: 264

You can do it using GetRange function:

List<double> part1= big_list.GetRange(0, 8);//Retrieves 8 items starting with index '0'
List<double> part2= big_list.GetRange(8, 9);//Retrieves 9 items starting with index '8'

Or if you don't want to give different names to all parts, you can create a list of lists:

List<List<double>> listoflists = new List<List<double>>();
listoflists.Add(big_list.GetRange(0, 8));//Retrieves 8 items starting with index '0'
listoflists.Add(big_list.GetRange(8, 9));//Retrieves 9 items starting with index '8'            
for(int i=0; i<listoflists.Count;i++){
    for(int j=0; j<listoflists[i].Count; j++){
        Console.Write(listoflists[i][j] + "  ");
    }
    Console.WriteLine();
}

Upvotes: 2

Mahyar Mottaghi Zadeh
Mahyar Mottaghi Zadeh

Reputation: 1325

if you are insisting on do the operation in one single for statement you can use the following code

const int arrSize = 6;
var splitedLists = new List<List<int>>(arrSize);

var defaultTake = 8;
var defaultSkip = 0;

for (var i = 1; i <= arrSize; i++)
{
    if (i >= 3)
        defaultSkip--;

    splitedLists.Add(array.Skip(defaultSkip).Take(defaultTake + 1).ToList());

    if (i >= 2)
        defaultTake++;

    defaultSkip = defaultSkip + defaultTake + 1;
}

Upvotes: 0

Steve
Steve

Reputation: 216243

It is a very simple approach with the IEnumerable extensions Skip and Take

List<double> first = bigList.Take(8).ToList();
List<double> second = bigList.Skip(8).Take(8).ToList();
List<double> third = bigList.Skip(16).Take(9).ToList();
List<double> fourth = bigList.Skip(25).Take(10).ToList();
List<double> fifth = bigList.Skip(35).Take(11).ToList();

// The last one is without Take to get every remaining element
List<double> sixth = bigList.Skip(46).ToList();

Of course you should check if the indexes are correct for your requirements. These indexes doesn't skip any elements from your bigList

You can make this approach more generic with something like this

void Main()
{
    var bigList = GetYourBigList();

    List<Tuple<int, int>> positions = new List<Tuple<int, int>>
    {
        new Tuple<int, int>(0,8),
        new Tuple<int, int>(8,8),
        new Tuple<int, int>(16,9),
        new Tuple<int, int>(25,10),
        new Tuple<int, int>(35,11),
        new Tuple<int, int>(46,13)
    };

    List<List<int>> result = SplitTheList(bigList, positions);

    foreach (var list in result)
    {
        foreach (var temp in list)
            Console.WriteLine(temp);
        Console.WriteLine("--------------------");
    }
 }

 List<List<int>> SplitTheList(List<int> r, List<Tuple<int, int>> positions)
 {
    List<List<int>> result = new List<List<int>>();
    foreach(var x in positions)
       result.Add(r.Skip(x.Item1).Take(x.Item2).ToList());
    return result;

 }

Upvotes: 5

Related Questions