Skip to content

Instantly share code, notes, and snippets.

@yKimisaki
Last active June 25, 2018 09:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yKimisaki/b7c2086e2e186dc117ea0cc26decac64 to your computer and use it in GitHub Desktop.
Save yKimisaki/b7c2086e2e186dc117ea0cc26decac64 to your computer and use it in GitHub Desktop.
using System;
using System.Collections;
using System.Collections.Generic;
namespace Tonari.Linq
{
public static class Enumerable_ShrinkEx
{
public static IEnumerable<TSource[]> Shrink<TSource>(this IEnumerable<TSource> source)
{
return new ShrinkEnumerable<TSource, TSource>(source, x => x, null);
}
public static IEnumerable<TSource[]> Shrink<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
{
return new ShrinkEnumerable<TSource, TKey>(source, keySelector, null);
}
public static IEnumerable<TSource[]> Shrink<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
{
return new ShrinkEnumerable<TSource, TKey>(source, keySelector, comparer);
}
}
public class ShrinkEnumerable<TSource, TKey> : IEnumerable<TSource[]>, IEnumerable
{
private IEnumerable<TSource> _source;
private Func<TSource, TKey> _keySelector;
private IEqualityComparer<TKey> _comparer;
public ShrinkEnumerable(IEnumerable<TSource> source, Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
{
this._source = source;
this._keySelector = keySelector;
this._comparer = comparer ?? EqualityComparer<TKey>.Default;
}
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
public IEnumerator<TSource[]> GetEnumerator()
{
var results = new List<TSource[]>();
var isInitlalized = false;
var isShrinked = false;
var @base = default(TSource);
var prev = default(TSource);
var result = new List<TSource>();
foreach(var element in this._source)
{
if (isInitlalized)
{
var baseKey = this._keySelector(@base);
isShrinked = this._comparer.Equals(baseKey, this._keySelector(prev));
if (this._comparer.Equals(baseKey, this._keySelector(element)))
{
prev = element;
result.Add(element);
continue;
}
}
isInitlalized = true;
if (isShrinked)
{
isShrinked = false;
results.Add(result.ToArray());
result.Clear();
}
@base = prev = element;
result.Add(element);
}
if (isInitlalized)
{
results.Add(result.ToArray());
}
return results.GetEnumerator();
}
}
}
@yKimisaki
Copy link
Author

前から順番にたどっていって、重複している要素があれば配列にまとめる。
同じ要素が以前にあっても、連続して同じ要素がなければ別になる。

var array = new [] { 1, 2, 2, 3, 3, 3, 1, 1, 2, 2, 3, };
array.Shrink().ToArray(); //  { { 1, }, { 2, 2, }, { 3, 3, 3, }, { 1, 1, }, { 2, 2, }, { 3, }, }; 

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment