George Phillipson
George Phillipson

Reputation: 860

Display match for only 3 consecutive numbers

How can I display only 3 consecutive numbers for example in my code below I only want it to return 4, as that appears 3 times.

9 is 4 times so do not want that and 7 is twice so not what want that.

The code I currently have display 9

int[] intArray = { 9, 9, 9, 9, 6, 4, 4, 4, 7, 7 };

var adjacentDuplicateNumbers = intArray
    .Skip(1)
    .Where((value, index) => value == intArray[index])
    .Distinct();

var enumerable = adjacentDuplicateNumbers as int[] ?? adjacentDuplicateNumbers.ToArray();
if (enumerable.Any())
{
    Console.WriteLine("{0} is a consecutive number and is repeated 3 times.", enumerable.First());
}
else
{
    Console.WriteLine("no consecutive number found.");
}

Upvotes: 2

Views: 403

Answers (3)

TVOHM
TVOHM

Reputation: 2742

var results = intArray.Distinct()
    .ToDictionary(k => k, v => intArray.Count(x => x == v))
    .Where(x => x.Value == 3)
    .Select(x => x.Key);

Take the district elements in the array. Use these as keys in a dictionary that map to the number of occurrences of this key in the original array. Use Where to only select pairs that match the required count (3). Use Select to return the resulting keys - in this example only 4.

Upvotes: 0

wertzui
wertzui

Reputation: 5730

Sometimes a simple foor loop is enough (and should be faster than linq)

int[] intArray = { 9, 9, 9, 9, 6, 4, 4, 4, 7, 7 };
var minus2 = intArray[0];
var minus1 = intArray[1];
var result = new List<int>();
for(int i = 2; i < intArray.Length; i++)
{
    var current = intArray[i];
    if(minus2 == minus1 && minus1 == current)
    {
        result.Add(current);
    }
    minus2 = minus1;
    minus1 = current;
}

Upvotes: 0

Flat Eric
Flat Eric

Reputation: 8111

Using the extension method of this post: LINQ to find series of consecutive numbers

public static IEnumerable<IEnumerable<T>> GroupWhile<T>(this IEnumerable<T> seq, Func<T, T, bool> condition)
{
  T prev = seq.First();
  List<T> list = new List<T>() { prev };

  foreach (T item in seq.Skip(1))
  {
    if (condition(prev, item) == false)
    {
      yield return list;
      list = new List<T>();
    }
    list.Add(item);
    prev = item;
  }

  yield return list;
}

Usage:

var res = intArray.GroupWhile((a, b) => a == b).
          Where(x => x.Count() == 3).Select(x => x.First());

Upvotes: 3

Related Questions