title: Split a list of files into multiple smaller lists based on file size in c#
body: <p>I am writing a method that will take a large list of files and split them into smaller lists that contain an equal total of disk space. Eg. a list with 1 file that is 100kb and another with 100 files that are 1kb each. </p>
  
  <p>The code i have does the following. If all files in a list total to more than 500kb i want to split this list into smaller lists. This means if i have a total count of 600kb i will have 2 lists. I want to add 300kb (or as close as possible) worth of files to each of these lists. </p>
  
  <p>I have code written that will do this fairly well, but there is a common type of scenario that will mess this up. If i have 99 files. 99 are 1kb each and the last file is 400kb. This code will go back and forth adding 1 file to each lists until both lists will have 49 files with 49kb in each of the lists, but now the final file which is huge will mean that 1 list will be 49kb and the other 449kb. I need a smart way to divide the files so that the 400kb file ends up in a list on its own. </p>
  
  <pre><code>int listcount = (int)Math.Ceiling(totalsize / listlimit); //500kb
  
      List&lt;string&gt;[] lists = new List&lt;string&gt;[listcount];
      double[] memorytotals = new double[listcount]; // this array will keep track of what the file size total is in each of the arrays.
  
      foreach(string file in filelist)
      {
          double size = new FileInfo(file).Length;
  
          int pos = 0;
          for (int i = 0; i &lt; memorytotals.Length; i++)
      {
          if (memorytotals[i] &lt; memorytotals[pos]) { pos = i; }
      }
         if(size &gt; memorytotals[pos])
          {
              //get the next smallest array that is not pos
              int pos2 = 0;
              for (int i = 0; i &lt; memorytotals.Length; i++)
              {
                  if (memorytotals[i] &lt; memorytotals[pos2] &amp;&amp; pos2 != pos) 
                  { 
                      pos2 = i; 
                  }
              }
  
              //if moving all contents of the smallest array into the second smallest array make for a smaller size than just putting the larger file directly into the smaller array than do it.
              double newlistTotal = memorytotals[pos] + memorytotals[pos2];
              if(newlistTotal &lt; size)
              {
                  lists[pos2].AddRange(lists[pos]);
                  //empty the list in order to add the new larger file to this list.
                  lists[pos].Clear();
              }
          }
          lists[pos].Add(file);
      }
  </code></pre>