2017-06-21 112 views
-1

我有一個對象類型集合A。我想知道是否可以創建另一個集合,包括子集A,如if A[i].Something == 'a' && A[i+1].Something == 'b',然後將其添加到新集合中。Linq列表幫助

新系列將是KeyValue雙列表,使得(Key = A[i], Value = A[i+1])

我想做到這一點使用lambda進出口。有人可以指導我嗎?

回答

4

由於標準的LINQ不支持LeadLag)方法(看看More Linq如果你堅持的LINQ樣的解決方案),我建議實施一個簡單的發電機:

private static IEnumerable<KeyValue<MyClass, MyClass>> MakePairs(
    IEnumerable<MyClass> source) { 

    if (null == source) 
    throw new ArgumentNullException("source"); 

    MyClass prior = default(MyClass); 
    bool first = true; 

    foreach (var current in source) { 
    if (first) { 
     prior = current; 
     first = false; 

     continue; 
    } 

    if (prior != null && current != null && 
     prior.Something == "A" && current.Something == "B") //TODO: put right condition 
     yield return new KeyValue(prior, current); 

    prior = current; 
    } 
} 

... 

IEnumerable<MyClass> source = ... 

var result = MakePairs(source).ToList(); 
+0

您對'prior = source.FirstOrDefault();'然後是'foreach(source.skip(1)中的var current)'有什麼看法?這將使'if'多餘 – Default

+0

@默認:在source.FirstOrDefault()的情況下,然後在foreach中掃描集合*兩次*(即使第一次掃描僅爲一個項目)。這可能是一個*問題*如果1.收集開放是昂貴的*(例如,我們有一個文件,RDBMS查詢等)2.如果集合是可變的(比如,某人在'FirstOrDefault()'和'foreach')。當收集的來源*未知*,掃描一次* –

0

您可以使用Select,它有一個重載獲取索引,在這種情況下可用於檢索列表中的下一個項目。

var newCollection = collection.Select 
           ((a, i) => new 
            { A = a 
            , NextA = (i + 1) < collection.Length ? collection[i + 1] : null 
            } 
           ); 

從那裏你可以寫謂詞你想:

var filteredCollection = newCollection.Where 
             (x => x.A.Something == "a" 
              && x.NextA?.Something == "b" 
             ); 
1

將這項工作?

IEnumerable<string> list; 
IEnumerable<string> list2 = list.Skip(1); 

string test1 = "a"; 
string test2 = "b"; 

var result = list 
    .Zip(list.Skip(1), 
     (x, y) => Tuple.Create(x, y)) 
    .Where(r => r.Item1 == test1 && r.Item2 == test2) 
    .ToDictionary(r => r.Item1, 
       r => r.Item2); 
1

另一種獲取鍵/值對的方法是使用除第一個以外的所有項目壓縮集合。理論上應該處理任何保留順序的枚舉。如果 '科爾' 是源:

coll.Zip(coll.Skip(1), (a1,a2) => new {Key = a1.Something, Value = a2.Something}) 

要爲值 'a' 和 'B' 僅得到:

coll.Zip(coll.Skip(1), (a1,a2) => new {Key = a1.Something, Value = a2.Something}) 
     .Where(kv=>kv.Key == "a" && kv.Value == "b") 
0

OP具有收藏,所以我開始了一個ICollection的:

public static IEnumerable<KeyValuePair<A, A>> KeyValueSelecting(ICollection<A> source) { 
     if (null == source) { throw new ArgumentNullException(nameof(source)); } 
     for (var i = 0; i < source.Count - 1; i++) { 
      var firstElement = source.ElementAtOrDefault(i); 
      if (firstElement?.Something != "A") { yield break; } 
      var seceondElement = source.ElementAtOrDefault(i + 1); 
      if (seceondElement?.Something != "B") { yield break; } 
      yield return new KeyValuePair<A, A>(firstElement, seceondElement); 
     } 
    }