0

I have a List with n elements. Before I can use the items I must group them so 1,2,3,4 goes into one group and 4,5,6,7 goes into the next group ... n

my current c# code is:

List<List<Job>> groupedJobs = AlotOfcSharpCode(unGroupedJobs);

A have the feeling that all that can be placed with something like

var groupedJobs = unGroupedJobs.SelectMany().GroupBy().SomeOtherLinq

My basic problem is to iterate over the source list and take every 4 element so 1,2,3,4 goes into one group and 4,5,6,7 goes into the next group using linq.

This is my input:

List<Job> JobList = new List<Job>();
JobList.Add( new Job { JobID = 1, } );
JobList.Add( new Job { JobID = 2, } );
JobList.Add( new Job { JobID = 3, } );
JobList.Add( new Job { JobID = 4, } );
JobList.Add( new Job { JobID = 5, } );
JobList.Add( new Job { JobID = 6, } );
JobList.Add( new Job { JobID = 7, } );
JobList.Add( new Job { JobID = 8, } );
JobList.Add( new Job { JobID = 9, } );
JobList.Add( new Job { JobID = 10, } );

My desired outcome is a structure like

List<List<Job>> Groups = List<List<Job>>();

List<Job> group = new List<Job>();
JobList.Add( new Job { JobID = 1, } );
JobList.Add( new Job { JobID = 2, } );
JobList.Add( new Job { JobID = 3, } );
JobList.Add( new Job { JobID = 4, } );

group = new List<Job>();
JobList.Add( new Job { JobID = 5, } );
JobList.Add( new Job { JobID = 6, } );
JobList.Add( new Job { JobID = 7, } );
JobList.Add( new Job { JobID = 8, } );

group = new List<Job>();
JobList.Add( new Job { JobID = 9, } );
JobList.Add( new Job { JobID = 10, } );

The usage of this grouping is that I need to iterate each group and do stuff.

      List<Job> allJobs = stateStorage.Value.Jobs;

      var groupedJobs = GroupJobs(allJobs);
      
      foreach (var group in groupedJobs)
      {
          var doSomething = new DoSomething(group);
      }

      return something;
  }

  private static IEnumerable<IEnumerable<Job>> GroupJobs(IEnumerable<Job> allJobs)
  {
      var groupsIndex = new List<List<Job>>();

      var counter = 0;
      var group = new List<Job>();

      foreach (var job in allJobs)
      {
          if (counter == 4)
          {
              groupsIndex.Add(group);
              group = new List<Job>();
          }

          group.Add(job);

          counter++;
      }

      return groupsIndex;
  }
Tony
  • 1,394
  • 5
  • 22
  • 48
  • Possible duplicate with [How to use Linq to group every N number of rows](https://stackoverflow.com/questions/860305/how-to-use-linq-to-group-every-n-number-of-rows) – OmerCD Sep 06 '20 at 10:23

2 Answers2

1

You can use the following group function:

JobList.GroupBy(item => (item.JobID - 1) / 4)

Group function is integer division - so values 1 - 4 will receive group value 0, values 5 - 8 will have group value 1 and so on. Looks like this is what you are looking for.

Michael Kokorin
  • 474
  • 2
  • 8
1

May be this could Help.

Source:

public class Job
{
    public int JobID { get; set; }

    public static Job[] GetJobs()
    {
        var jobList = new[] {
        new Job { JobID = 1 },
        new Job { JobID = 2},
        new Job { JobID = 3},
        new Job { JobID = 4},
        new Job { JobID = 5},
        new Job { JobID = 6},
        new Job { JobID = 7},
        new Job { JobID = 8},
        new Job { JobID = 9},
        new Job { JobID = 10}
    };
    return jobList;
    }

    public override string ToString()
    {
        return $"Job {{ JobID={JobID} }}";            
    }
}

Group Query Using Linq:

       //Data Source
        var source = Job.GetJobs();
  
        //Query Creation
        var query = from index in Enumerable.Range(0, source.Length) 
                    group source[index] by index / 4;

        //Query Execution
        foreach (var item in query)
        {
            Console.WriteLine($"Group : {item.Key}");               
            item.ToList().ForEach(it => Console.WriteLine(it.ToString()));               
        }
       
        Console.ReadLine();

Expected Ouput:

Console Output Image

Naren
  • 56
  • 3