2013-10-15 37 views
0

我得到了一個字符串列表,我想在其中執行將每個項目與其餘項目連接的操作。下面的測試目前失敗了,我認爲這個連接並不是我應該使用的正確的linq方法 - 請讓我知道如何完成這個任務?輸出的模式應該告訴投影應該這樣,如果不是規則很簡單:拿一個項目,並與所有其他項目串聯,然後移動到下一個item.Test如下:在字符串列表上設置操作

[Test] 
     public void Should_concatenate_all_items() 
     { 
      var items = new List<string> {"a", "b", "c", "d"}; 

      var concatenatedList = items .Join(items , x => x, y => y, (x, y) => string.Concat(x, y)); 

      foreach (var item in concatenatedList) 
      {     
       //Should output:ab 
       //Should output:ac 
       //Should output:ad 
       //Should output:bc 
       //Should output:bd 
       //Should output:cd 
       Console.WriteLine(item); 
      } 
     } 

:我正在使用.NET 3.5。

+0

什麼是'potentialItems'和它的元素呢?這是完整的輸出還是樣本? – Cyral

+0

@Cyral:查看編輯 – Mike

+0

好的,那是我認爲的 – Cyral

回答

3

你可以使用這樣的事情:

var concatenatedList = 
    from x in items.Select((str, idx) => new { str, idx }) 
    from y in items.Skip(x.idx + 1) 
    select x.str + y; 

或者用流利的語法:

var concatenatedList = 
    items.Select((str, idx) => new { str, idx }) 
     .SelectMany(x => items.Skip(x.idx + 1), (x, y) => x.str + y); 
+1

+1。下面的問題有更多的示例[cross join](http://stackoverflow.com/questions/56547/how-do-you-perform-a-cross-join-with-linq-to-sql)在這裏使用。 –

0
var concatenatedList = (from i in items 
        from x in items 
        where i != x 
        select string.Concat(i, x)).ToList(); 

對於您所列出的精確的輸出:

var concatenatedList = (from i in items 
        from x in items 
        where i != x && items.IndexOf(i) < items.IndexOf(x) 
        select string.Concat(i, x)).ToList(); 
+0

我給了另外一個,當我寫第一個的時候並不清楚。 –

0

我想我的解決方案可能會矯枉過正,但在真實的情況下在這種情況下,它可能更有幫助。此外,我無法在Linq中找到乾淨的方法。 Linq的Except似乎不適合這一點。

您可以使用IEnumerator爲您枚舉值。

public class ConcatEnum : IEnumerator 
{ 
    public List<String> _values; 

    // Enumerators are positioned before the first element 
    // until the first MoveNext() call. 
    int position1 = 0; 
    int position2 = 0; 

    public ConcatEnum(List<String> list) 
    { 
     _values = list; 
    } 

    public bool MoveNext() 
    { 
     position2 = Math.Max(position2 + 1, position1 + 1); 
     if (position2 > _values.Count - 1){ 
      position1++; 
      position2 = position1 + 1; 
     } 

     return position1 < _values.Count - 1; 
    } 

    public void Reset() 
    { 
     position1 = 0; 
     position2 = 0; 
    } 

    object IEnumerator.Current 
    { 
     get 
     { 
      return Current; 
     } 
    } 

    public String Current 
    { 
     get 
     { 
      try 
      { 
       return _values[position1] + _values[position2]; 
      } 
      catch (IndexOutOfRangeException) 
      { 
       throw new InvalidOperationException(); 
      } 
     } 
    } 

    public IEnumerator GetEnumerator() 
    { 
     this.Reset(); 
     while (this.MoveNext()) 
     { 
      yield return Current; 
     } 
    } 
} 

這樣稱呼它:

var items = new List<string> { "a", "b", "c", "d" }; 
foreach (var i in new ConcatEnum(items)) 
{ 
    //use values here 
}