Linq帮助列表

时间:2017-06-21 07:39:19

标签: c# linq

我有一个对象类型A的集合。我想知道我是否可以创建另一个集合,包括A的子集,例如if A[i].Something == 'a' && A[i+1].Something == 'b',然后将其添加到新集合中。

新集合将是KeyValue对的列表,(Key = A[i], Value = A[i+1])

我想用lambda exp完成这个。有人可以指导我吗?

5 个答案:

答案 0 :(得分:5)

由于标准 Linq 不支持 LeadLag)方法(如果您坚持,请查看More Linq在Linq-like解决方案上),我建议实现一个简单的生成器:

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

答案 1 :(得分:2)

获取键/值对的另一种方法是使用除第一项之外的所有项目对集合进行压缩。理论上应该在任何保留顺序的可枚举上工作。如果'coll'是您的来源:

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")

答案 2 :(得分: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);

答案 3 :(得分: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"
                                       );

答案 4 :(得分: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);
        }
    }