获取符合条件或第一项的第一项

时间:2010-12-07 08:11:01

标签: c# linq-to-objects

我想获得满足给定条件的第一个项目,如果没有任何项目符合该条件,我只想获得第一个项目

这是我目前所做的和有效的方法,但我不喜欢它。是否有更优雅的方法在一个LINQ查询中执行相同的操作?

LookupLine lookup;
Func<KeyValuePair<int,LookupLine>,bool> criteria = 
    (kv) => !kv.Value.Gruppe.StartsWith("SF");

if (lookupLines.Any(criteria))
{
    lookup = lookupLines.First(criteria).Value;
}
else if (lookupLines.Any())
{
    lookup = lookupLines.First().Value;
}

FirstRelevantGroup = lookup.Gruppe;

3 个答案:

答案 0 :(得分:2)

嗯,对于单行,你可以做

lookupLines.OrderBy(kv => kv.Value.Gruppe.StartsWith("SF") ? 2 : 1).First();

但我认为您的解决方案更能传达您的意图,尽管可以简化为:

LookupLine lookup = lookupLines.FirstOrDefault(kv => !kv.Value.Gruppe.StartsWith("SF"));
if(lookup == null) {
   lookup = lookupLines.First();
}

FirstRelevantGroup = lookup.Value.Gruppe;

现在,您可以将上述内容变为合并,但同样会失去一些可读性:

FirstRelevantGroup = (
     lookupLines.FirstOrDefault(kv => !kv.Value.Gruppe.StartsWith("SF"))
     ?? lookupLines.First()
).Value.Gruppe;

答案 1 :(得分:1)

我想要一种扩展方法。

public static T FirstIfNotFound<T>(this IEnumerable<T> source, Func<T,bool> predicate)
{
   if (source==null||predicate==null) throw new ArgumentNullException();
   return source.Any(predicate) ? source.FirstOrDefault(predicate) : source.First();
}

答案 2 :(得分:1)

我最喜欢的一个班轮是

C:\Perforce\test\undo>p4 annotate -c foo
//stream/main/undo/foo#4 - integrate change 138 (text)
135: this
138: is
135: a
137: test  **CHANGE B**
135: file

C:\Perforce\test\undo>p4 filelog foo
//stream/main/undo/foo
... #4 change 138 integrate on 2020/02/08 by Samwise@compy386 (text) 'undid A'
... ... undid //stream/main/undo/foo#2
... #3 change 137 edit on 2020/02/08 by Samwise@compy386 (text) 'change B'
... #2 change 136 edit on 2020/02/08 by Samwise@compy386 (text) 'change A'
... ... undone by //stream/main/undo/foo#4
... #1 change 135 add on 2020/02/08 by Samwise@compy386 (text) 'test file'

这将返回

  • 第一个匹配元素(如果有)。
  • 注释匹配的第一个元素。
  • 如果列表为空,则为null。