Note that there are some explanatory texts on larger screens.

plurals
  1. PODoes Linq provide a way to easily spot gaps in a sequence?
    text
    copied!<p>I am managing a directory of files. Each file will be named similarly to <code>Image_000000.png</code>, with the numeric portion being incremented for each file that is stored.</p> <p>Files can also be deleted, leaving gaps in the number sequence. The reason I am asking is because I recognize that at some point in the future, the user could use up the number sequence unless I takes steps to reuse numbers when they become available. I realize that it is a million, and that's a lot, but we have 20-plus year users, so "someday" is not out of the question.</p> <p>So, I am specifically asking whether or not there exists a way to easily determine the gaps in the sequence without simply looping. I realize that because it's a fixed range, I could simply loop over the expected range.</p> <p>And I will unless there is a better/cleaner/easier/faster alternative. If so, I'd like to know about it.</p> <p>This method is called to obtain the next available file name:</p> <pre><code>public static String GetNextImageFileName() { String retFile = null; DirectoryInfo di = new DirectoryInfo(userVars.ImageDirectory); FileInfo[] fia = di.GetFiles("*.*", SearchOption.TopDirectoryOnly); String lastFile = fia.Where(i =&gt; i.Name.StartsWith("Image_") &amp;&amp; i.Name.Substring(6, 6).ContainsOnlyDigits()).OrderBy(i =&gt; i.Name).Last().Name; if (!String.IsNullOrEmpty(lastFile)) { Int32 num; String strNum = lastFile.Substring(6, 6); String strExt = lastFile.Substring(13); if (!String.IsNullOrEmpty(strNum) &amp;&amp; !String.IsNullOrEmpty(strExt) &amp;&amp; strNum.ContainsOnlyDigits() &amp;&amp; Int32.TryParse(strNum, out num)) { num++; retFile = String.Format("Image_{0:D6}.{1}", num, strExt); while (num &lt;= 999999 &amp;&amp; File.Exists(retFile)) { num++; retFile = String.Format("Image_{0:D6}.{1}", num, strExt); } } } return retFile; } </code></pre> <p><strong>EDIT: in case it helps anyone, here is the final method, incorporating Daniel Hilgarth's answer:</strong></p> <pre><code>public static String GetNextImageFileName() { DirectoryInfo di = new DirectoryInfo(userVars.ImageDirectory); FileInfo[] fia = di.GetFiles("Image_*.*", SearchOption.TopDirectoryOnly); List&lt;Int32&gt; fileNums = new List&lt;Int32&gt;(); foreach (FileInfo fi in fia) { Int32 i; if (Int32.TryParse(fi.Name.Substring(6, 6), out i)) fileNums.Add(i); } var result = fileNums.Select((x, i) =&gt; new { Index = i, Value = x }) .Where(x =&gt; x.Index != x.Value) .Select(x =&gt; (Int32?)x.Index) .FirstOrDefault(); Int32 index; if (result == null) index = fileNums.Count - 1; else index = result.Value - 1; var nextNumber = fileNums[index] + 1; if (nextNumber &gt;= 0 &amp;&amp; nextNumber &lt;= 999999) return String.Format("Image_{0:D6}", result.Value); return null; } </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload