这个问题的标题有点奇怪,所以谢谢你。
我想要达到的目的是在数字上使用groupby,但仅限于计数值为3 时。
为了澄清......作为一个例子,我有以下数组值。
int[] nums= new int[] { 1, 1, 1, 3, 1 };
如果我在这样的nums上做一个小组
var vals = dice.GroupBy(t => t).Select(p => new { Value = p.Key, Count = p.Count() }).ToList();
它将返回以下
{Value = 1, Count = 4},
{Value = 3, Count = 1}
我真正想要的是这个。
{Value = 1, Count = 3},
{Value = 1, Count = 1}
{Value = 3, Count = 1}
可以使用GroupBy方法来实现这一目标,还是需要采用不同的方法?
答案 0 :(得分:2)
您可以使用此answer的此Chunkify
修改版本为每个组制作块:
static class ChunkExtension
{
public static IEnumerable<IEnumerable<T>> Chunkify<T>(
this IEnumerable<T> source, int size)
{
if (source == null) throw new ArgumentNullException("source");
if (size < 1) throw new ArgumentOutOfRangeException("size");
using (var iter = source.GetEnumerator())
{
while (iter.MoveNext())
{
var chunk = new List<T>();
chunk.Add(iter.Current);
for (int i = 1; i < size && iter.MoveNext(); i++)
chunk.Add(iter.Current);
yield return chunk;
}
}
}
}
int[] nums = new int[] { 1, 1, 1, 3, 1 };
var groups = nums.GroupBy(n => n)
.Select(g => g.Chunkify(3)
.Select(x => new { Value = g.Key, Count = x.Count() }))
.SelectMany(g => g);
你得到这样的东西:
{Value = 1, Count = 3},
{Value = 1, Count = 1}
{Value = 3, Count = 1}
答案 1 :(得分:2)
我不认为有一个原生的LINQ解决方案可以满足您的需求。 (或者,如果存在,它可能会有点大而且不实用。)但是,你可以写一个应该完成这项工作的扩展方法:
public static class IEnumerableExtensions
{
public class Grouping<TKey, TElement> : IGrouping<TKey, TElement>
{
readonly List<TElement> elements;
public Grouping(TKey key, List<TElement> elems)
{
Key = key;
elements = elems;
}
public TKey Key { get; private set; }
public IEnumerator<TElement> GetEnumerator()
{
return this.elements.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); }
}
public static IEnumerable<IGrouping<TKey, TElement>> GroupByConcurrent<TSource, TKey, TElement>(
this IEnumerable<TSource> source,
Func<TSource, TKey> keySelector,
Func<TSource, TElement> elementSelector)
where TKey : IEquatable<TKey>
{
if (source == null)
throw new ArgumentNullException("source");
TKey currentKey = default(TKey);
List<TElement> currentList = null;
foreach (var s in source)
{
var key = keySelector.Invoke(s);
var elem = elementSelector.Invoke(s);
if (!key.Equals(currentKey) || currentList == null)
{
if (currentList != null && currentList.Count > 0)
yield return new Grouping<TKey, TElement>(currentKey, currentList);
currentKey = key;
currentList = new List<TElement>();
}
currentList.Add(elem);
}
if (currentList != null && currentList.Count > 0)
yield return new Grouping<TKey, TElement>(currentKey, currentList);
}
}
您可以这样称呼它:
int[] nums = new int[] { 1, 1, 1, 3, 1 };
var concurGrouped = nums.GroupByConcurrent(t => t, t => t)
.Select(p => new { Value = p.Key, Count = p.Count() })
.ToList();
// Contents of concurGrouped:
//
// { Value = 1, Count = 3},
// { Value = 1, Count = 1},
// { Value = 3, Count = 1}