22890

Getting last x consecutive items with LINQ

Question:

My question is similar to this one: <a href="https://stackoverflow.com/questions/7112435/finding-consecutive-items-in-list-using-linq" rel="nofollow">Finding Consecutive Items in List using Linq</a>. Except, I'd like to get the last consecutive items that have no gaps. For example:

2, 4, 7, 8

output

7,8

Another example:

4,5,8,10,11,12

output

10,11,12

How can that be done?

Answer1:

I'm assuming in that you want the last consecutive sequence with more than one member... so from the sequence

{4, 5, 8, 10, 11, 12, 15}

you're expecting the sequence:

{10, 11, 12}

I've indicated the line to remove if the last sequence is permitted to have only a single member, giving a sequence of

{15}

Here's the linq:

new[] {4, 5, 8, 10, 11, 12, 15} .Select((n,i) => new {n, i}) .GroupBy(x => x.n - x.i) //this line will group consecutive nums in the seq .Where(g => g.Count() > 1) //remove this line if the seq {15} is expected .Select(x => x.Select(xx => xx.n)) .LastOrDefault()

There's a hidden assumption here that the numbers of the sequence are in ascending order. If this isn't the case, it will be necessary to enroll the powers of microsoft's extension method for <a href="http://msdn.microsoft.com/en-us/library/cc138361.aspx" rel="nofollow">finding contiguous items in a sequence</a>. Let me know if this is the case.

Answer2:

This works and is probably easier and more efficient than LINQ in this case:

var list = new[] { 2, 4, 7, 8 }; List<int> lastConsecutive = new List<int>(); for (int i = list.Length - 1; i > 0; i--) { lastConsecutive.Add(list[i]); if (list[i] - 1 != list[i - 1]) break; if(i==1 && list[i] - 1 == list[i - 1]) // needed since we're iterating just until 1 lastConsecutive.Add(list[0]); } lastConsecutive.Reverse();

Answer3:

I realise this is both late and wordy, but this is probably the fastest method here that still uses LINQ.

Test lists:

var list1 = new List<int> {2,4,7,8}; var list2 = new List<int> {4,5,8,10,11,12,15};

The method:

public List<int> LastConsecutive(List<int> list) { var rev = list.AsEnumerable().Reverse(); var res = rev.Zip(rev.Skip(1), (l, r) => new { left = l, right = r, diff = (l - r) }) .SkipWhile(x => x.diff != 1) .TakeWhile(x => x.diff == 1); return res.Take(1).Select(x => x.left) .Concat(res.Select(x => x.right)) .Reverse().ToList(); }

This one goes from back to front and checks elements pairwise, only taking elements from when they start being consecutive (the SkipWhile) until they end being consecutive (the TakeWhile).

Then it does some work to pull the relevant pairwise numbers out (left number from the 'original' list and then all the right numbers), and reverses it back. Similar efficiency to the imperative version, but in my opinion simpler to read because of LINQ.

Recommend

  • Configuring AutoMapper to fulfil ITypeConverter constructor dependecies with Autofac
  • Get Index of last active columns per Row in Excel using Open XML
  • How do i use DirectoryInfo and FileInfo to get all files and add the sorted files to a List?
  • c# Cast string as IEnumerable
  • Star * symbol found on second line of Fortran function declaration
  • Ajax Returning different output in same logic
  • PyParsing: Is it possible to globally suppress all Literals?
  • Delete object in core data, failed to match the Swift Array Element type
  • Ordering a Union Query in MS Access SQL
  • Count the number of non-null values in a Spark DataFrame
  • Thread Synchronization with IntentService
  • const char **a = {“string1”,“string2”} and pointer arithametic
  • Is in C# List something like vector.reserve(n) in C++
  • Gradle - How to detect --debug flag from command line?
  • Can't run Appium tests on iOS 10 on real device
  • Converting float[,] to list in f#?
  • How to sort things out in ListView?
  • How to customize whisker lines on a geom_box plot differently than the lines of the box itself
  • Extract data between rows r
  • OAuth and the YouTube API
  • Crafting a LINQ based solution to determine if a set of predicates are satisfied for a pair of colle
  • Adding directive inside the directive programatically
  • insert radio value multiple data codeigniter in database to one row?
  • Universal Image Loader reuse images
  • How to pass nginx proxy url for socket
  • xtable package: Skipping some rows in the output
  • Breeze - Deleted Items nav properties bug
  • Splitting given String into two variables - php
  • NetLogo BehaviorSpace - Measure runs using reporters
  • Is my CUDA kernel really runs on device or is being mistekenly executed by host in emulation?
  • Read text file and split every line in MSBuild
  • javaw.exe and eclipse startup problems
  • How to add a column to a Pandas dataframe made of arrays of the n-preceding values of another column
  • Build own AppleScript numerical error handling
  • Unit Testing MVC Web Application in Visual Studio and Problem with QTAgent
  • Rails 2: use form_for to build a form covering multiple objects of the same class
  • -fvisibility=hidden not passed by compiler for Debug builds
  • embed rChart in Markdown
  • need help with bizarre java.net.HttpURLConnection behavior
  • Busy indicator not showing up in wpf window [duplicate]