2

I need a bit of help. I have a list of 5k elements that is a path to files. I split the list into five smaller lists. My problem is how can I loop over the list of lists and pick the elements from all five at the same iteration.

Sample of code. The source list:

List<string> sourceDir = new List<string>(new string[] { "C:/Temp/data/a.txt", "C:/Temp/data/s.txt", "C:/Temp/data/d.txt", "C:/Temp/data/f.txt", "C:/Temp/data/g.txt", "C:/Temp/data/h.txt", "C:/Temp/data/j.txt", "C:/Temp/data/k.txt", "C:/Temp/data/l.txt", "C:/Temp/data/z.txt"});

Splitting the list into smaller list:

public static List<List<T>> Split<T>(IList<T> source)
        {
            return source
                .Select((x, i) => new { Index = i, Value = x })
                .GroupBy(x => x.Index / 2)
                .Select(x => x.Select(v => v.Value).ToList())
                .ToList();
        }

Result:

var list = Split(sourceDir);

As result in the variable list, I get five lists. How can I now access items from all lists at one iteration for further processing? Something like:

foreach (string fileName in list[0])
            {
                foreach (string fileName1 in list[1])
                {
                    foreach (string fileName2 in list[2])
                    {
                        foreach (string fileName3 in list[3])
                        {
                            foreach (string fileName4 in list[4])
                            {
                                //have items from all lists 
                                Console.WriteLine("First name is: " + fileName);
                                Console.WriteLine("Second name is: " + fileName1);
                                Console.WriteLine("Third name is: " + fileName2);
                                Console.WriteLine("Fourth name is: " + fileName3);
                                Console.WriteLine("Fift name is: " + fileName4);
                               

                                

                                break;
                                

                            }
                            break;

                        }
                        break;
                    }
                    break;

                }

                continue;
            }

the above foreach loop is just to get an idea of what I need.

linasster
  • 139
  • 8
  • 1
    why do you want to split the list? – Mario Vernari Aug 07 '22 at 13:35
  • Yes, it is unclear the reason for splitting the list in sublists. Could you explain why do you need this? It looks like an [XY Problem](https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem#duplicate=0) – Steve Aug 07 '22 at 13:43
  • @Steve : The data is two columns a & s. – jdweng Aug 07 '22 at 13:49
  • foreach (var row in list). You are returning a generic list not a string. So you need to use var. Each row will have two columns. So you can use First() and Last() to get the two columns. – jdweng Aug 07 '22 at 13:52
  • The reason is I want to do multithread file copying. So I would pass those files to the different thread to be moved to another location. – linasster Aug 07 '22 at 13:55

1 Answers1

2

Multithreading on file IO operations is not always a good choice. You add the overhead for thread switches, but the disk access is bound to other considerations. Look here for example

Does multithreading make sense for IO-bound operations?

However, just to answer your question, you can use a standard for loop instead of all those foreach, the only thing you need to take care is the case when the sublists don't have the same number of elements. (files number not exactly divisible by 5)

int maxIndex = Math.Max(list[0].Count,
               Math.Max(list[1].Count,
               Math.Max(list[2].Count,
               Math.Max(list[3].Count, list[4].Count))));
for (int x = 0; x < maxIndex; x++)
{
    string item0 = x < list[0].Count ? list[0][x] : "No item";
    string item1 = x < list[1].Count ? list[1][x] : "No item";
    string item2 = x < list[2].Count ? list[2][x] : "No item";
    string item3 = x < list[3].Count ? list[3][x] : "No item";
    string item4 = x < list[4].Count ? list[4][x] : "No item";
    Console.WriteLine("First name is: " + item0);
    Console.WriteLine("Second name is: " + item1);
    Console.WriteLine("Third name is: " + item2);
    Console.WriteLine("Fourth name is: " + item3);
    Console.WriteLine("Fifth name is: " + item4);
}
Steve
  • 213,761
  • 22
  • 232
  • 286