我有一个包含这些条目的数组:
{1, 1, 2, 2, 3,3,3, 4}
我希望将它们转换为(在这种情况下为3个列表):
{1,2,3,4}
{1,2,3}
{3}
有没有办法用LINQ或SQL做到这一点?我想这个操作有一个数学术语,不幸的是我不知道......
或者我必须使用循环吗?
=======
编辑:我无法真正描述逻辑,所以这里有更多的例子..它或多或少在数组上循环多次并且每个数字一次(但每一个数字只有一次)直到没有数字左{1,1,2,2,3,3,3,4,5} 将会 {1,2,3,4,5} {1,2,3} {3}
或
{1,1,2,2,2,3,3,3,4,5} 将会 {1,2,3,4,5} {1,2,3} {2,3}
答案 0 :(得分:10)
private IEnumerable<List<int>> FooSplit(IEnumerable<int> items)
{
List<int> source = new List<int>(items);
while (source.Any())
{
var result = source.Distinct().ToList();
yield return result;
result.ForEach(item => source.Remove(item));
}
}
用法:
int[] items = { 1, 1, 2, 2, 3, 3, 3, 4 };
foreach(var subList in FooSplit(items))
{
// here you have your three sublists
}
这是另一个解决方案,它的可读性较差,但性能会更好:
private IEnumerable<IEnumerable<int>> FooSplit(IEnumerable<int> items)
{
var groups = items.GroupBy(i => i).Select(g => g.ToList()).ToList();
while (groups.Count > 0)
{
yield return groups.Select( g =>
{ var i = g[0]; g.RemoveAt(g.Count - 1); return i; });
groups.RemoveAll(g => g.Count == 0);
}
}
答案 1 :(得分:1)
这就完成了工作:
static void Main(string[] args)
{
int[] numbers = {1, 1, 2, 2, 3, 3, 3, 3, 4, 5, 5};
List<int> nums = new List<int>(numbers.Length);
nums.AddRange(numbers);
while (nums.Count > 0)
{
int[] n = nums.Distinct().ToArray();
for (int i = 0; i < n.Count(); i++)
{
Console.Write("{0}\t", n[i]);
nums.Remove(n[i]);
}
Console.WriteLine();
}
Console.Read();
}
答案 2 :(得分:1)
这是一个替代的控制台应用程序:
class Program
{
class Freq
{
public int Num { get; set; }
public int Count { get; set; }
}
static void Main(string[] args)
{
var nums = new[] { 1, 1, 2, 2, 3, 3, 3, 4 };
var groups = nums.GroupBy(i => i).Select(g => new Freq { Num = g.Key, Count = g.Count() }).ToList();
while (groups.Any(g => g.Count > 0))
{
var list = groups.Where(g => g.Count > 0).Select(g => g.Num).ToList();
list.ForEach(li => groups.First(g => g.Num == li).Count--);
Console.WriteLine(String.Join(",", list));
}
Console.ReadKey();
}
}