2013-01-13 158 views
3

我有這些條目的單個陣列:LINQ:分離單列表,多個列表

{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,3,3,3,4,5} 將是 {1,2,3,4,5} {1,2,3} {2, 3}

+4

什麼是分離的邏輯是什麼? – Oded

+0

如果你的數組= {1,2,2,3,3,3,3,4,5},怎麼辦? –

+0

{1,2,3,4,5},{2,3},{3},{3}? –

回答

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); 
    } 
} 
+2

非常優雅的解決方案。人們必須愛上疊加。 Thx所有! – David

+0

令人驚歎的!!!!!!!!!!! –

+0

好,但從性能的角度來看並不是最佳--O(N * N)複雜度 – SergeyS

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(); 
    } 
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(); 
    } 

}