2013-10-15 19 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 
}