Skip to main content
Code Review

Return to Question

Commonmark migration
Source Link

This function divides a sequence into partitions, where a partition is a list of consecutive matching elements.

Example

Input: (A, A, B, B, B, A, C, C)

Output: ((A, A), (B, B, B), (A), (C, C))

I've tried to make this code "obviously correct", but it still doesn't look that way to me.

public static IEnumerable<List<T>> PartitionBy<T, PK>(this IEnumerable<T> sequence, Func<T, PK> partitionKey)
{
 return sequence.PartitionBy(partitionKey, EqualityComparer<PK>.Default);
}
public static IEnumerable<List<T>> PartitionBy<T>(this IEnumerable<T> sequence, IEqualityComparer<T> comparer)
{
 return sequence.PartitionBy(item => item, comparer);
}
public static IEnumerable<List<T>> PartitionBy<T, X>(this IEnumerable<T> sequence, Func<T, X> partitionKey, IEqualityComparer<X> comparer)
{
 var itr = sequence.GetEnumerator();
 if (!itr.MoveNext())
 {
 // empty sequence was passed in, so return empty sequence
 yield break;
 }
 // Start the first partition.
 var currentList = new List<T>(new[] { itr.Current });
 while (itr.MoveNext())
 {
 var key1 = partitionKey(currentList[0]);
 var key2 = partitionKey(itr.Current);
 if (comparer.Equals(key1, key2))
 {
 // continue current partition
 currentList.Add(itr.Current);
 }
 else
 {
 // yield current partition and start a new one
 yield return currentList;
 currentList = new List<T>(new[] { itr.Current });
 }
 }
 // We know it has at least 1 element here.
 yield return currentList;
}

This function divides a sequence into partitions, where a partition is a list of consecutive matching elements.

Example

Input: (A, A, B, B, B, A, C, C)

Output: ((A, A), (B, B, B), (A), (C, C))

I've tried to make this code "obviously correct", but it still doesn't look that way to me.

public static IEnumerable<List<T>> PartitionBy<T, PK>(this IEnumerable<T> sequence, Func<T, PK> partitionKey)
{
 return sequence.PartitionBy(partitionKey, EqualityComparer<PK>.Default);
}
public static IEnumerable<List<T>> PartitionBy<T>(this IEnumerable<T> sequence, IEqualityComparer<T> comparer)
{
 return sequence.PartitionBy(item => item, comparer);
}
public static IEnumerable<List<T>> PartitionBy<T, X>(this IEnumerable<T> sequence, Func<T, X> partitionKey, IEqualityComparer<X> comparer)
{
 var itr = sequence.GetEnumerator();
 if (!itr.MoveNext())
 {
 // empty sequence was passed in, so return empty sequence
 yield break;
 }
 // Start the first partition.
 var currentList = new List<T>(new[] { itr.Current });
 while (itr.MoveNext())
 {
 var key1 = partitionKey(currentList[0]);
 var key2 = partitionKey(itr.Current);
 if (comparer.Equals(key1, key2))
 {
 // continue current partition
 currentList.Add(itr.Current);
 }
 else
 {
 // yield current partition and start a new one
 yield return currentList;
 currentList = new List<T>(new[] { itr.Current });
 }
 }
 // We know it has at least 1 element here.
 yield return currentList;
}

This function divides a sequence into partitions, where a partition is a list of consecutive matching elements.

Example

Input: (A, A, B, B, B, A, C, C)

Output: ((A, A), (B, B, B), (A), (C, C))

I've tried to make this code "obviously correct", but it still doesn't look that way to me.

public static IEnumerable<List<T>> PartitionBy<T, PK>(this IEnumerable<T> sequence, Func<T, PK> partitionKey)
{
 return sequence.PartitionBy(partitionKey, EqualityComparer<PK>.Default);
}
public static IEnumerable<List<T>> PartitionBy<T>(this IEnumerable<T> sequence, IEqualityComparer<T> comparer)
{
 return sequence.PartitionBy(item => item, comparer);
}
public static IEnumerable<List<T>> PartitionBy<T, X>(this IEnumerable<T> sequence, Func<T, X> partitionKey, IEqualityComparer<X> comparer)
{
 var itr = sequence.GetEnumerator();
 if (!itr.MoveNext())
 {
 // empty sequence was passed in, so return empty sequence
 yield break;
 }
 // Start the first partition.
 var currentList = new List<T>(new[] { itr.Current });
 while (itr.MoveNext())
 {
 var key1 = partitionKey(currentList[0]);
 var key2 = partitionKey(itr.Current);
 if (comparer.Equals(key1, key2))
 {
 // continue current partition
 currentList.Add(itr.Current);
 }
 else
 {
 // yield current partition and start a new one
 yield return currentList;
 currentList = new List<T>(new[] { itr.Current });
 }
 }
 // We know it has at least 1 element here.
 yield return currentList;
}
Source Link

Partitioning a sequence into sublists

This function divides a sequence into partitions, where a partition is a list of consecutive matching elements.

Example

Input: (A, A, B, B, B, A, C, C)

Output: ((A, A), (B, B, B), (A), (C, C))

I've tried to make this code "obviously correct", but it still doesn't look that way to me.

public static IEnumerable<List<T>> PartitionBy<T, PK>(this IEnumerable<T> sequence, Func<T, PK> partitionKey)
{
 return sequence.PartitionBy(partitionKey, EqualityComparer<PK>.Default);
}
public static IEnumerable<List<T>> PartitionBy<T>(this IEnumerable<T> sequence, IEqualityComparer<T> comparer)
{
 return sequence.PartitionBy(item => item, comparer);
}
public static IEnumerable<List<T>> PartitionBy<T, X>(this IEnumerable<T> sequence, Func<T, X> partitionKey, IEqualityComparer<X> comparer)
{
 var itr = sequence.GetEnumerator();
 if (!itr.MoveNext())
 {
 // empty sequence was passed in, so return empty sequence
 yield break;
 }
 // Start the first partition.
 var currentList = new List<T>(new[] { itr.Current });
 while (itr.MoveNext())
 {
 var key1 = partitionKey(currentList[0]);
 var key2 = partitionKey(itr.Current);
 if (comparer.Equals(key1, key2))
 {
 // continue current partition
 currentList.Add(itr.Current);
 }
 else
 {
 // yield current partition and start a new one
 yield return currentList;
 currentList = new List<T>(new[] { itr.Current });
 }
 }
 // We know it has at least 1 element here.
 yield return currentList;
}
lang-cs

AltStyle によって変換されたページ (->オリジナル) /